看到一個大佬寫的控制異步[并發(fā)]數(shù)的函數(shù),核心思想就是在并發(fā)數(shù)大于限制的時候狈涮,暫時先把操作放入通過promise組裝一下垃沦,然后放入數(shù)組懂牧,每次執(zhí)行完異步回調(diào)后就將操作按先入先出的順序取出锋边,然后執(zhí)行皱坛,保證最大并發(fā)數(shù)在限制范圍內(nèi)。
代碼如下:
export class LimitPromise {
private limit: number; // 最大限制數(shù)
private count: number; // 目前并發(fā)的數(shù)量
private taskQueue: any[]; // 如果并發(fā)數(shù)等于最大限制豆巨,則把新加的異步操作用數(shù)組存起來
constructor(limit: number) {
this.limit = limit;
this.count = 0;
this.taskQueue = [];
}
private createTask(
asyncFn: Function,
args: any[],
resolve: (value: unknown) => void,
reject: (reason?: any) => void,
) {
return () => {
asyncFn(...args)
.then(resolve)
.catch(reject)
.finally(() => {
this.count--;
if (this.taskQueue.length) {
let task = this.taskQueue.shift();
task();
}
});
this.count++;
};
}
public call(asyncFn: Function, ...args: any[]) {
return new Promise((resolve, reject) => {
const task = this.createTask(asyncFn, args, resolve, reject);
if (this.count >= this.limit) {
this.taskQueue.push(task);
} else {
task();
}
});
}
}
let limitP = new LimitPromise(3)
用一個異步函數(shù)sleep驗證一下
function sleep(sec: number) {
console.log('..............');
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('等待了' + sec + '秒');
resolve('');
}, sec * 1000);
});
}
limitPromise.call(sleep, 1);
limitPromise.call(sleep, 2);
limitPromise.call(sleep, 3);
limitPromise.call(sleep, 4);
limitPromise.call(sleep, 5);
limitPromise.call(sleep, 6);