自定义队封装(Queue)
/**
* @class Queue
* @description 队列
*/
class Queue {
/**
* 构造函数
* @param {Number} concurrence 同步数
*/
constructor(concurrence = 1) {
/**
* 同步执行数
*/
this.concurrence = concurrence;
/**
* 当前正在运行的任务数
*/
this.running = new Set();
/**
* 任务队列
*/
this.queue = [];
/**
* 标记队列是否暂停
*/
this.paused = false;
}
/**
* 加入队列
* @param {Function} callback callback(symbol,done) 执行回调任务
* @param {Boolean} unshift 是否优先
*/
push(callback = (done = () => { }) => { }, unshift = false) {
// 为任务生成唯一的标识符
let symbol = Symbol();
// 将任务添加到队列中
if (!!unshift) this.queue.unshift({ symbol, callback });
else this.queue.push({ symbol, callback });
// 开始执行队列中的任务
if (this.paused === false) this.next();
// 返回标识
return symbol;
}
/**
* 队列优先
* @param {Symbol} symbol
*/
unshift(symbol = Symbol()) {
this.pause();
let element = null;
let index = this.queue.findIndex(task => task.symbol === symbol);
if (index !== -1) element = this.queue.splice(index, 1)[0];
if (element !== null) this.queue.unshift(element);
this.resume();
return element;
}
/**
* 移除任务
* @param {Symbol} symbol
*/
remove(symbol = Symbol()) {
this.pause();
let index = this.queue.findIndex(task => task.symbol === symbol);
if (index !== -1) this.queue.splice(index, 1);
this.resume();
}
/**
* 下一个任务
*/
next() {
while (this.paused === false && this.running.size < this.concurrence && this.queue.length) {
// 从队列中取出任务
let { symbol, callback } = this.queue.shift();
// 增加当前正在运行的任务数
this.running.add(symbol);
callback(symbol, () => {
// 减少当前正在运行的任务数
this.running.delete(symbol)
// 执行下一个任务
this.next();
});
}
}
/**
* 暂停队列
*/
pause() { this.paused = true; }
/**
* 恢复队列
*/
resume() { this.paused = false; this.next(); }
/**
* 清空队列
*/
clear() { this.queue = []; }
/**
* 停止队列
*/
stop() {
this.clear();
this.running.clear();
}
};
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
CaptainTwo!
喜欢就支持一下吧