15行代码实现js并发控制

869 阅读1分钟
const limitPromise = (limit, list) => {
  let curr = 0, res = [];
  const initial = [];
  const run = (func) => {
    if (curr > list.length) {
      return Promise.resolve();
    }
    const e = func().then((d) => res.push(d));
    return e.then(() => run(list[curr++]));
  }
  for (; curr < limit && curr < list.length; curr++) {
    initial.push(list[curr]);
  }
  return Promise.all(initial.map(func => run(func))).then(() => res);
}

解释

首先初始化同时运行 limit 个任务,每个任务在结束的时候去拉目标队列中没有被执行的任务,这样保证了每次都有 limit 个进程在执行

例子

const timer = i => new Promise((resolve, reject) => setTimeout(() => resolve(i), i));

console.log(+new Date)
limitPromise(3, [
  () => timer(1000),
  () => timer(2000),
  () => timer(3000),
  () => timer(4000),
  () => timer(5000)
]).then(res => {
console.log(+new Date)
  console.log('res', res);
})
// 1611798912742
// 1611798919750
// res [ 1000, 2000, 3000, 4000, 5000 ]
// 1611798919750 - 1611798912742 = 7008