# 实现 Promise.concurrent 并发

# 实现并发请求

//模拟请求
const createWork = (time) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(time);
    }, time);
  });
};

//模拟异步任务需要的时间
const promises = [5000, 1000, 2000, 2000, 2000, 4000];

Promise.concurrent = (promises, createWork, max = 3) => {
  return new Promise((resolve, reject) => {
    let results = [];
    let resultNumber = 0;
    let currentIndex = 0;
    let len = promises.length;
    const startTime = Date.now();
    console.log(`开始任务:${startTime}`);
    const start = async () => {
      //当还有任务 并且有 并发空间
      while (currentIndex < len && max > 0) {
        const index = currentIndex;
        const work = createWork(promises[index]); //创建异步请求
        max--;
        currentIndex++;
        console.log(
          `${
            Date.now() - startTime
          }s 开始的请求,并发还有${max},当前开始的任务下标${index}`
        );
        const result = await work;
        max++;
        console.log(`结束,并发还有${max},当前结束的任务下标${index}`);
        results[index] = result;
        resultNumber++;
        if (resultNumber === len) {
          resolve(results);
        } else {
          start();
        }
      }
    };

    for (let i = 0; i < len; i++) {
      start();
    }
  });
};

console.time();
Promise.concurrent(promises, createWork, 3).then((res) => {
  console.log(res);
  console.timeEnd();
});

//结果
// 开始任务:1654253633557
// 0s 开始的请求,并发还有2,当前开始的任务下标0
// 0s 开始的请求,并发还有1,当前开始的任务下标1
// 1s 开始的请求,并发还有0,当前开始的任务下标2
//  结束,并发还有1,当前结束的任务下标1
// 1029s 开始的请求,并发还有0,当前开始的任务下标3
//  结束,并发还有1,当前结束的任务下标2
// 2008s 开始的请求,并发还有0,当前开始的任务下标4
//  结束,并发还有1,当前结束的任务下标3
// 3377s 开始的请求,并发还有0,当前开始的任务下标5
//  结束,并发还有1,当前结束的任务下标4
//  结束,并发还有2,当前结束的任务下标0
//  结束,并发还有3,当前结束的任务下标5
//  (6) [5000, 1000, 2000, 2000, 2000, 4000]
//  default: 8386.843994140625 ms
Last Updated: 6/3/2022, 8:05:38 PM