以下为ChatGPT自动生成的解答,正确与否请自行判断。

BFE.devAI解答 - JavaScript 代码题
92. Promise节流

解答:

这道题需要通过手动创建一个任务队列,来限制同时进行的 API 请求数量。具体实现如下:

function throttlePromises(promises, maxConcurrency) {
  let index = 0; // 记录已经发起请求的 promise 的索引
  let activeCount = 0; // 记录正在进行中的请求数量
  let results = new Array(promises.length); // 用于保存最终结果的数组

  // 定义一个递归函数,用于处理请求队列中的下一个任务
  function processNext() {
    // 如果所有任务已经完成,则直接返回包含结果的 Promise
    if (index === promises.length && activeCount === 0) {
      return Promise.resolve(results);
    }

    // 如果可以执行新的任务,则执行
    if (index < promises.length && activeCount < maxConcurrency) {
      const currentIndex = index++;
      activeCount++;
      const currentPromise = promises[currentIndex]();

      // 将任务 promise 的结果放入结果数组中
      currentPromise
        .then((result) => {
          results[currentIndex] = result;
        })
        .catch((error) => {
          results[currentIndex] = error;
        })
        .finally(() => {
          activeCount--;
        });

      // 递归调用 processNext(),进入下一轮处理
      return processNext();
    }

    // 如果不能执行新的任务,则等待之前的任务完成后再执行
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(processNext());
      }, 10);
    });
  }

  // 调用 processNext(),返回 Promise
  return processNext();
}

上述代码中,通过一个递归的 processNext() 函数来处理任务队列中的下一个任务,确保最多只有 maxConcurrency 个任务同时进行。如果目前正在进行的请求数小于 maxConcurrency,并且还有未发起的请求,则会取出下一个未执行的 API 请求并立即执行。

如果已经发起的请求达到了 maxConcurrency 的上限,则等待 10 毫秒后再次调用 processNext(),直到有请求完成之后才继续进行下一个任务。

最后,使用 throttlePromises() 函数即可在限制请求数量的情况下获取所有结果:

throttlePromises(callApis, 5)
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });