今天,项目提测之后,测试同学提出了一个bug,就是一些新建任务从创建到完成需要一个时间段,任务详情页和列表页就会任务状态不会实时更新,需要用户手动刷新才能实现。
针对这个问题,我考虑通过轮询来实现。
实现轮询的两种方式:websoket和定时器
复制代码
通过和项目组的同学讨论,先使用定时器来实现,以后再优化成websoket方式。
一、项目涉及的六个状态:
pending(待调度) running(运行中) success(成功) failure(失败) revoked(被终止) offlineSkip(下线跳过)
复制代码
6种状态划分为2类:
完成状态:success、failure、revoked、offlineSkip
未完成状态:pending、running
复制代码
6种状态会出现2种结果:
pending->running->success/failure/revoked/offlineSkip
running->success/failure/revoked/offlineSkip
复制代码
判断任务是否处于完成状态:
// 判断任务是否已完成
export const finished = (status: string): boolean => {
status = status.toLowerCase();
return status === 'failure' || status === 'revoked' || status === 'success' || status === 'offlineskip';
};
复制代码
二、实现详情页的需求。
详情页的就比较简单了。首次调用详情接口时,查看返回的任务状态,如果返回的是完成状态,直接展示该状态就可以了。如果是未完成状态,就需要设置一个定时器来重复调用详情接口,直至返回完成状态,清楚定时器。
async getJobDetail (DaemonJobId, index) {
const detail: any = await getJobDetail({
_releaseId: this.releaseId,
_jobId: DaemonJobId
});
const { Status } = detail.data;
if (!finished(Status)) {
this.timer = window.setTimeout(() => {
this.getJobDetail(DaemonJobId, index);
}, 5000);
} else {
clearTimeout(this.timer);
}
}
复制代码
三、实现列表页面的需求。
列表页因为涉及翻页功能(page>1),所以不能通过简单的调用列表接口(page=1)来实现。如果一直刷新列表页面,该页面就无法实现翻页功能。
所以这块实现,我先去遍历了列表信息,未完成状态去调详情接口,直到返回完成状态,通过set直接页面视图。
// 循环列表数据
list.forEach(async (ele, index) => {
if (!finished(ele.Status)) {
this.getJobDetail(ele.DaemonJobId, index);
}
});
// 调用详情接口
async getJobDetail (DaemonJobId, index) {
const detail: any = await getJobDetail({
_releaseId: this.releaseId,
_jobId: DaemonJobId
});
const { Status, FinishedTime } = detail.data;
if (finished(Status)) {
this.$set(this.jobList[index], 'Status', Status);
this.$set(this.jobList[index], 'FinishedTime', FinishedTime);
}
if (!finished(Status) && Status === 'Running') {
this.$set(this.jobList[index], 'Status', Status);
this.timer = window.setTimeout(() => {
this.getJobDetail(DaemonJobId, index);
}, 5000);
}
if (!finished(Status) && Status === 'Pending') {
this.timer = window.setTimeout(() => {
this.getJobDetail(DaemonJobId, index);
}, 1000 * 60);
}
}
复制代码
如果同时创建多个任务,每次运行中的任务之用一个,别的都是待调度状态。考虑性能,待调度状态就每隔1min调用一次详情接口就可以了,直到它变为运行中再每隔5s调用一次详情接口。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END