废话不多说,直接上代码:
import axios from 'axios'
// 利用Promise模拟任务队列,从而实现请求池效果。function requestQueue(concurrency) {
concurrency = concurrency || 6;
const taskList = []; // 请求池
let current = 0;
const dequeue = () => {
while (current < concurrency && taskList.length) {
current++;
// 获取并立即执行队列中的下一个任务
const task = taskList.shift();
if (task) {
task().then(res => {
// 成功的请求逻辑
console.log('Success:', res);
}).catch(error => {
// 失败的请求逻辑
console.error('Error:', error);
}).finally(() => {
current--;
dequeue(); // 无论成功或失败,都继续处理队列中的下一个任务
});
}
}
};
return (promiseFactory) => {
taskList.push(promiseFactory); // 入列,这里push的是返回Promise的函数
dequeue();
};
}
// 测试需保持接口请求通畅
const enqueue = requestQueue(6);
for (let i = 0; i < 10; i++) {
enqueue(() => axios.get('./static/login.json?a=' + i)); // 这里传入的是返回Promise的函数
}
实现原理:
// enqueue 是一个返回函数的函数,这个函数接收一个 promise factory
const enqueue = requestQueue(6);
// 在这里,我们传入一个函数,这个函数返回 axios 的 Promise
enqueue(() => axios.get('./static/login.json?a=' + i));
总结:
enqueue 方法并不直接处理 Promise;它处理的是可以生成 Promise 的函数。这些函数被存储在队列中,并由 dequeue 方法在适当的时候执行,从而生成并处理 Promise。这种设计允许我们控制同时执行的请求数量(即并发性),因为 dequeue 方法会确保在任何时候最多只有 concurrency 个 Promise 在处理中。