async-pond
Version:
一个使用 promise 来解决并发异步控制的方案,无任何依赖
117 lines • 4.75 kB
JavaScript
"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