控制并发请求
实现方式:
function concurrentPoll(promiseList, limit) {
const restPromiseList = Array.prototype.slice.call(promiseList);
const length = promiseList.length;
const result = [];
let handling = 0; // handling count
let resolved = 0; // resolved count
return new Promise((resolve, reject) => {
// Core method
// trigger request function
const run = () => {
if (restPromiseList.length === 0) return;
const index = length - restPromiseList.length;
const fn = restPromiseList.shift();
handling++;
Promise.resolve(fn())
.then((res) => {
result[index] = res; // save response data
})
.catch((err) => {
console.log(`error:`, err);
})
.finally(() => {
handling--;
resolved++;
if (resolved === length) {
resolve(result); // all settled, return result
} else {
run(); // recursion
}
});
};
for (let i = 0; i < limit; i++) {
run();
}
});
}
测试代码:
function mockHttpRequestList(delayList) {
return delayList.map((delay, index) => () =>
new Promise((resolve, reject) => {
console.log('run: ', index, delay);
setTimeout(() => {
console.log('resolved:', index, delay);
resolve(index);
}, delay);
})
);
}
const httpRequestList = mockHttpRequestList([200, 20, 100, 300, 600, 30]);
// test
concurrentPoll(httpRequestList, 3);