UNPKG

async-pond

Version:

一个使用 promise 来解决并发异步控制的方案,无任何依赖

117 lines 4.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var lib_1 = require("./lib"); var AsyncPoolPro = /** @class */ (function () { function AsyncPoolPro(poolLimit, options) { this.poolLimit = 3; this.promisePool = []; this.poolControlers = []; this.poolIndex = 0; this.whileControl = false; this.promiseGroups = {}; this.options = { isReTry: false, retryNum: 3, }; this.promisePool = []; // 存储所有的异步任务,且当前异步任务均为pending态 this.poolControlers = []; //异步请求的参数 this.poolLimit = poolLimit || 3; //并发限制数量 this.poolIndex = 0; this.whileControl = false; if ((0, lib_1.isObject)(options)) { Object.assign(this.options, options); } } AsyncPoolPro.prototype.push = function (poolParams, iteratorFn) { var _a; var _this = this; var flag = Symbol(); var poolControlers = (Array.isArray(poolParams) ? poolParams : [poolParams]).map(function (i) { return ({ iteratorFn: iteratorFn, param: i, flag: flag, }); }); (_a = this.poolControlers).push.apply(_a, poolControlers); this.promiseGroups[flag] = { length: poolControlers.length, finishNum: 0, pendingPromises: [], }; this.asyncPool(this.promisePool.length === 0); return new Promise(function (resolve) { _this.promiseGroups[flag].resolve = resolve; }); }; /** * 延迟生成Promise异步 * @param poolControlers 异步请求的参数 */ AsyncPoolPro.prototype.generatorPromise = function (poolControlers) { var _this = this; if (poolControlers === void 0) { poolControlers = this.poolControlers; } var _a = poolControlers[this.poolIndex], iteratorFn = _a.iteratorFn, param = _a.param, flag = _a.flag; var group = this.promiseGroups[flag]; var p = Promise.resolve() .then(function () { return iteratorFn(param); }) .finally(function () { var finishPromiseIndex = _this.promisePool.indexOf(p); _this.promisePool.splice(finishPromiseIndex, 1); _this.poolControlers.splice(finishPromiseIndex, 1); _this.poolIndex--; group.finishNum++; if (group.length === group.finishNum) { // 当前组都结束pending后,执行group group.resolve && group.resolve(Promise.allSettled(group.pendingPromises)); } }); group.pendingPromises.push(p); this.promisePool.push(p); // 保存新的异步任务 this.options.afterInitSingleAsync && this.options.afterInitSingleAsync(this.promisePool); if (this.promisePool.length >= this.poolLimit) { return Promise.race(this.promisePool); // 等待较快的任务执行完成 } }; /** * 并发控制逻辑 * @param {boolean} isInit 是否初始化控制? */ AsyncPoolPro.prototype.asyncPool = function (isInit) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var flag, group, racePromise; return (0, tslib_1.__generator)(this, function (_a) { switch (_a.label) { case 0: if (!(isInit || this.whileControl)) return [3 /*break*/, 5]; this.whileControl = false; flag = this.poolControlers[this.poolIndex].flag; group = this.promiseGroups[flag]; _a.label = 1; case 1: if (!(this.poolIndex < this.poolControlers.length)) return [3 /*break*/, 4]; racePromise = this.generatorPromise(); if (!racePromise) return [3 /*break*/, 3]; return [4 /*yield*/, (0, lib_1.to)(racePromise)]; case 2: _a.sent(); _a.label = 3; case 3: this.poolIndex++; return [3 /*break*/, 1]; case 4: //while循环结束标识 this.whileControl = true; _a.label = 5; case 5: return [2 /*return*/]; } }); }); }; return AsyncPoolPro; }()); exports.default = AsyncPoolPro; //# sourceMappingURL=async-pond.js.map