以下为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);
});