跳到正文

手写练习/异步控制

GitHub

手写请求并发执行

中等异步请求并发控制

代码实现

JavaScript72 行
/**
 * requestConcurrent:限制并发数量地执行异步任务
 * @param {Function[]} tasks 异步任务函数数组,每一项执行后返回 Promise
 * @param {number} limit 最大并发数
 * @returns {Promise<Array>} 所有任务结果,顺序和 tasks 一致
 */

function requestConcurrent(tasks, limit = 3) {
  let index = 0
  let running = 0
  const result = []

  return new Promise((resolve, reject) =>{

    if (tasks.length === 0) {
      resolve([]);
      return;
    }

    function runTask(){
      if(index === tasks.length && running === 0){
        resolve(result)
        return
      }

      while(index < tasks.length && running < limit){
        const curIndex = index
        const task = tasks[index]

        index++
        running++

        Promise.resolve(task()).then((res) => {
          result[curIndex] = res
        }).catch((err) => {
          result[curIndex] = err
        }).finally(()=>{
          running--
          runTask()
        })
      }
    }

    runTask()
  })
}

// ==================== 测试
function createTask(id, delay) {
  return () =>
    new Promise((resolve) => {
      setTimeout(() => {
        console.log(`任务 ${id} 完成`);
        resolve(id);
      }, delay);
    });
}

const tasks = [
  createTask(1, 300),
  createTask(2, 100),
  createTask(3, 200),
  createTask(4, 100),
];

requestConcurrent(tasks, 2)
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.error(err);
  });