任务队列的中断和恢复实现
概述
本文档描述了一个可暂停、可恢复的任务队列系统的设计与实现。该系统允许依次执行一系列任务,在所有任务完成后收集所有执行结果,并提供start
和pause
两个关键方法控制任务执行流程。
设计目标
- 顺序执行:任务按照添加顺序依次执行
- 原子性保证:每个任务执行不可中断,只能在任务间暂停
- 结果收集:所有任务完成后返回每个任务的执行结果
- 流程控制:提供启动和暂停功能
核心实现
类结构
js
class PausableTaskQueue {
constructor(tasks) {
this.tasks = tasks; // 任务数组
this.results = []; // 存储任务结果
this.currentIndex = 0; // 当前任务索引
this.isPaused = false; // 暂停状态标志
this.isRunning = false; // 运行状态标志
}
// 启动任务执行
start() {
// 实现细节见下文
}
// 暂停任务执行
pause() {
// 实现细节见下文
}
// 实际执行任务的内部方法
async _executeTasks() {
// 实现细节见下文
}
}
启动方法实现
js
start() {
if (this.isRunning) {
console.log('任务队列已在运行中');
return;
}
this.isRunning = true;
this.isPaused = false;
// 返回Promise以便调用者知道所有任务何时完成
return this._executeTasks()
.then(() => {
this.isRunning = false;
return this.results; // 返回所有任务结果
})
.catch(error => {
this.isRunning = false;
throw error;
});
}
暂停方法实现
js
pause() {
if (!this.isRunning) {
console.log('任务队列未运行,无法暂停');
return;
}
if (this.isPaused) {
console.log('任务队列已处于暂停状态');
return;
}
this.isPaused = true;
console.log('任务队列已暂停,将在当前任务完成后停止');
}
任务执行核心逻辑
js
async _executeTasks() {
// 遍历所有任务
while (this.currentIndex < this.tasks.length) {
// 检查暂停状态
if (this.isPaused) {
console.log('任务执行已暂停');
return; // 退出函数,停止执行后续任务
}
const task = this.tasks[this.currentIndex];
console.log(`开始执行任务 ${this.currentIndex + 1}/${this.tasks.length}`);
try {
// 执行当前任务(假设任务返回Promise)
const result = await task();
this.results.push(result);
console.log(`任务 ${this.currentIndex + 1} 完成`);
} catch (error) {
console.error(`任务 ${this.currentIndex + 1} 执行失败:`, error);
// 可以根据需要决定是否继续执行后续任务
// 这里选择将错误信息作为结果保存并继续执行
this.results.push({ error: error.message });
}
this.currentIndex++;
}
console.log('所有任务执行完成');
}
使用示例
js
// 示例任务定义
const tasks = [
() => new Promise(resolve => setTimeout(() => resolve('任务1结果'), 1000)),
() => new Promise(resolve => setTimeout(() => resolve('任务2结果'), 1500)),
() => new Promise(resolve => setTimeout(() => resolve('任务3结果'), 800)),
() => new Promise(resolve => setTimeout(() => resolve('任务4结果'), 1200)),
];
// 创建任务队列实例
const taskQueue = new PausableTaskQueue(tasks);
// 启动任务
const executionPromise = taskQueue.start();
// 2秒后暂停任务
setTimeout(() => {
taskQueue.pause();
// 3秒后重新启动
setTimeout(() => {
console.log('重新启动任务队列');
taskQueue.start().then(results => {
console.log('最终结果:', results);
});
}, 3000);
}, 2000);