先贴代码
function asyncLock(num = 2) {
let length = 0;
const task = [];
return function lock(fn){
return new Promise((r) => {
if (length < num) {
length ++;
return fn().then((data) => {
length--;
const cur = task.shift();
cur && lock(cur);
r(data);
});
}
task.push(() => fn().then(d => r(d)));
})
}
}
思路:
1、设置配置信息,请求并发数量 num,缓冲区task,当前执行中的任务数量
2、任务执行
- 如果遇到执行数量小于并发上限,则立即执行,执行结束,则看缓冲区是否有任务,有就拿出来执行,没有就结束
- 如果执行数量等于并发上限,则将任务放入缓冲区
3、返回每个任务的执行结果,用promise来进行结果的返回
测试代码
function request(val, time) {
return new Promise((r) => {
setTimeout(() => {
r(val)
}, time)
})
}
const limit = asyncLock(2);
limit(() => request(1, 1000)).then(d => console.log(d));
limit(() => request(2, 100)).then(d => console.log(d));
limit(() => request(3, 200)).then(d => console.log(d));
limit(() => request(4, 500)).then(d => console.log(d));
limit(() => request(5, 400)).then(d => console.log(d));
limit(() => request(6, 200)).then(d => console.log(d));
// 执行结果: 2 -> 3 -> 4 -> 1 -> 6 -> 5