这段代码的主要目的是并行地执行一系列异步任务,但限制并行任务的数量。以下是对这段代码的详细解释:
- 创建异步任务数组
const arr = [];
for (let i = 0; i < 100; i++) {
arr.push(() => new Promise((resolve) => {
setTimeout(() => {
console.log('done', i);
resolve();
}, 100 * i);
}));
};
这部分代码创建了一个包含100个异步任务的数组。每个任务都是一个返回Promise的函数。当这个函数被调用时,它会设置一个延迟(setTimeout),然后输出"done"和对应的索引i。延迟的时间是100 * i毫秒。
- 定义并行执行函数
const parallelRun = () => {
const runingTask = new Map();
const inqueue = (totalTask, max) => {
while (runingTask.size < max && totalTask.length) {
const newTask = totalTask.shift();
const tempName = totalTask.length;
runingTask.set(tempName, newTask);
newTask().finally(() => {
runingTask.delete(tempName);
inqueue(totalTask, max);
});
}
}
return inqueue;
};
这部分代码定义了一个名为parallelRun的函数,该函数返回一个名为inqueue的函数。inqueue函数接收两个参数:totalTask(要执行的任务数组)和max(并行执行的最大任务数)。
runingTask是一个Map,用于存储当前正在执行的任务。键是任务的唯一标识符(这里使用了totalTask.length作为临时标识符),值是任务函数。- 在
while循环中,代码会检查两个条件:runingTask的大小是否小于max以及totalTask是否还有任务。如果都满足,那么就从totalTask中取出一个任务,将其添加到runingTask中,并立即执行这个任务。 - 当任务完成时(无论是成功还是失败,因为使用了
finally),它会从runingTask中删除,并再次调用inqueue以尝试执行下一个任务。
- 执行并行任务
parallelRun()(arr, 6);
这行代码调用了parallelRun函数,并传入之前创建的异步任务数组arr和数字6。这意味着,在任何时候,最多只有6个任务会并行执行。一旦有任务完成,就会尝试从任务数组中取出下一个任务来执行,直到所有任务都完成。
总之,这段代码创建了一个任务队列,并允许你并行地执行这些任务,但并行的数量是有限的。这在处理大量异步任务但不想同时启动所有任务时非常有用,例如,当你想限制对外部API的并发请求数量时。