应用场景
在实际业务开发当中,经常有一些任务需要执行比较长的时间,那么就出现了两个问题:
- 前端:如何实现进度条的
显示
和步进
? - 后端:如果后端执行时间过长,前端就会收到
超时错误
。如何避免?
CabloyJS内置模块a-progress
轻松化解了上述问题,而且具有以下特点:
- 便捷的Api调用
- 支持层级显示
效果演示
前端调用
src/suite-vendor/test-party/modules/test-party/front/src/kitchen-sink/pages/progress.vue
onPerformStart() {
return new Promise((resolve, reject) => {
return this.$api.post('test/feat/progress').then(data => {
const progressId = data.progressId;
this.$view.dialog.progressbar({ progressId, title: this.$text('Working') }).then(data => {
console.log(data);
resolve();
}).catch(err => {
reject(err);
});
});
});
},
- 先调用后端Api取得
progressId
- 调用
$view.dialog.progressbar
显示进度条即可。此函数内部会自动从后端获取最新进度并更新显示
后端Api路由
src/suite-vendor/test-party/modules/test-party/backend/src/routes.js
// test/feat/progress
{ method: 'post', path: 'test/feat/progress', controller: 'testFeatProgress' },
后端Api控制器
src/suite-vendor/test-party/modules/test-party/backend/src/controller/test/feat/progress.js
module.exports = app => {
class ProgressController extends app.Controller {
async progress() {
// create progress
const progressId = await this.ctx.bean.progress.create();
// background
this.ctx.runInBackground(async () => {
await this._progressInBackground({ progressId });
});
// return progressId
this.ctx.success({ progressId });
}
async _progressInBackground({ progressId }) {
try {
// level one
await this._levelOne({ progressId, progressNo: 0 });
// progress done
await this.ctx.bean.progress.done({ progressId, message: this.ctx.text('Well Done') });
// ok
this.ctx.success(true);
} catch (err) {
// progress error
await this.ctx.bean.progress.error({ progressId, message: err.message });
// throw err
throw err;
}
}
async _levelOne({ progressId, progressNo }) {
const total = 2;
let current = 0;
for (let i = 0; i < total; i++) {
const text = `${this.ctx.text('Level One')}: ${i + 1}`;
await this.ctx.bean.progress.update({
progressId,
progressNo,
total,
progress: current++,
text,
});
// sleep
await this.ctx.bean.util.sleep(1500);
// level two
await this._levelTwo({ progressId, progressNo: progressNo + 1 });
}
}
async _levelTwo({ progressId, progressNo }) {
const total = 2;
let current = 0;
for (let i = 0; i < total; i++) {
const text = `${this.ctx.text('Level Two')}: ${i + 1}`;
await this.ctx.bean.progress.update({
progressId,
progressNo,
total,
progress: current++,
text,
});
// sleep
await this.ctx.bean.util.sleep(1500);
// level two
await this._levelThree({ progressId, progressNo: progressNo + 1 });
}
}
async _levelThree({ progressId, progressNo }) {
const total = 3;
let current = 0;
for (let i = 0; i < total; i++) {
const text = `${this.ctx.text('Level Three')}: ${i + 1}`;
await this.ctx.bean.progress.update({
progressId,
progressNo,
total,
progress: current++,
text,
});
// sleep
await this.ctx.bean.util.sleep(1500);
}
}
}
return ProgressController;
};
在这里实现了三个层级的进度条,而且为了直观性,这三个层级的代码直接展开(没有将共性代码提炼成公共函数) 。在实际开发中可以根据实际需要进行简化
- 流程说明
-
方法
progress
- 调用
ctx.bean.progress.create
生成一个progressId
- 调用
ctx.runInBackground
,以便在后台执行任务。否则,时间过长会导致前端收到超时错误
- 向前端返回
progressId
,从而显示进度条
- 调用
-
方法
_progressInBackground
- 使用
try/catch
结构包裹代码,便于捕获代码异常,更新进度条的状态 - 调用
ctx.bean.progress.update
更新进度 - 调用
ctx.bean.progress.done
完成进度 - 调用
ctx.bean.progress.error
登记错误信息
- 使用
- Api说明
- 方法
ctx.bean.progress.update
名称 | 说明 |
---|---|
progressId | 进度标识 |
progressNo | 当前进度层级编号,从0开始 |
total | 当前层级的任务总数 |
progress | 当前层级的当前任务进度,从0开始 |
text | 当前层级的当前任务进度的描述信息 |
- 方法
ctx.bean.progress.done
名称 | 说明 |
---|---|
progressId | 进度标识 |
message | 完成之后的提示信息 |
- 方法
ctx.bean.progress.error
名称 | 说明 |
---|---|
progressId | 进度标识 |
message | 错误信息 |
评论: