异步任务并发量
原题:请实现如下函数,可以并发请求数据,所有的 URL 地址在 urls 参数中,同时可以通过 max 参数控制请求的并发度,当所有请求结束之后,需要执行 callback 回调函数。
这里通过 sleep 模拟实现
async function sleep(n, name = "test") {
return new Promise((resolve) => {
console.log("start", name, n);
setTimeout(() => {
console.log("end", name, n);
resolve();
}, n);
});
}
// 限制并发数 items是异步函数队列
async function asyncPool({ max, items }) {
const results = [];
const pool = new Set();
for (const item of items) {
// 避免传入的不是 Promise
const fn = async (item) => await item();
const promise = fn(item);
results.push(promise);
pool.add(promise);
// 无论执行结果是成功还是失败都清除
const clean = () => pool.delete(promise);
promise.then(clean, clean);
if (pool.size >= max) {
// 等待最快的 Promise 执行完毕,才会执行下一次 for 循环
await Promise.race(pool);
}
}
return Promise.allSettled(results);
}
async function start() {
await asyncPool({
max: 2,
items: [
() => sleep(1000, "1000"),
() => sleep(4000, "4000"),
() => sleep(3500, "3500"),
() => sleep(5000, "5000"),
() => sleep(2000, "2000"),
],
});
console.log("all done");
}
start();
// 执行结果
// start 1000 1000
// start 4000 4000
// end 1000 1000
// start 3500 3500
// end 4000 4000
// start 5000 5000
// end 3500 3500
// start 2000 2000
// end 2000 2000
// end 5000 5000
// all done