UNPKG

ascor

Version:

一些常用的简单的js工具

98 lines (97 loc) 3.22 kB
import { EventEmitter } from "./EventEmitter"; export class Queue extends EventEmitter { constructor(config = { autoStart: false, workers: [], concurrency: Infinity }) { var _a, _b, _c; super(); this.workers = []; // 任务列表 this.workersCache = []; // 保存原来的任务列表 this.pending = 0; // 进行中的任务数量 this.autoStart = false; // 是否自动开始 this.isRuning = false; //是否执行中 this.isAborted = false; //是否中止了 this.concurrency = Infinity; //并发数量 this.autoStart = (_a = config === null || config === void 0 ? void 0 : config.autoStart) !== null && _a !== void 0 ? _a : false; // 是否自动开始 this.concurrency = (_b = config === null || config === void 0 ? void 0 : config.concurrency) !== null && _b !== void 0 ? _b : Infinity; //并发数量 this.push(...((_c = config === null || config === void 0 ? void 0 : config.workers) !== null && _c !== void 0 ? _c : [])); } /** * 获取执行中和队列中的数量,已执行完的不计算在内 */ get length() { return this.workers.length + this.pending; } /** * 添加队列任务 * @param {...any} workers 任务列表 */ push(...workers) { this.workers.push(...workers); this.workersCache.push(...workers); if (this.autoStart) { this.start(); } } /** * 执行下一任务 * @param {*} worker * @returns */ next(worker = null) { if (this.isAborted) { return false; } if (!worker) { if (this.length <= 0) { this.isRuning = false; this.emit("end", null); return false; } if (this.workers.length <= 0) { return false; } } this.pending++; let _worker = worker !== null && worker !== void 0 ? worker : this.workers.shift(); Promise.resolve(typeof _worker == "function" ? _worker() : _worker) .then((res) => { !this.isAborted && this.emit("success", res); }) .catch((error) => { !this.isAborted && this.emit("error", error, _worker); }) .finally(() => { this.pending--; !this.isAborted && this.next(); }); } /** * 开始任务 */ start() { if (this.isAborted) { // 如果之前已经中止过,则重新取之前的全部队列,重新执行 this.workers = [...this.workersCache]; } this.isAborted = false; if (!this.isRuning) { this.emit("start"); this.isRuning = true; } while (this.concurrency > this.pending && this.workers.length > 0 && !this.isAborted) { this.next(); } } /** * 中止任务 */ abort() { this.isAborted = true; if (this.isRuning) { this.isRuning = false; this.emit("end", new Error("The queue is aborted !")); } } end() { this.abort(); } }