问题描述
创建一个请求控件器,支持连续发起请求,如果超过请求限制则需要等其他请求返回之后再发送后续请求
function createFetch(limit: number) {
// todo
}
const myFetch = createFetch(3);
myFetch('/api/1').then(res => {
console.log('api-1');
}).catch(err => {})
myFetch('/api/2').then(res => {
console.log('api-2');
}).catch(err => {})
myFetch('/api/3').then(res => {
console.log('api-3');
}).catch(err => {})
// 需要等待上述请求返回
myFetch('/api/4').then(res => {
console.log('api-4');
}).catch(err => {})
思路解析
有两点注意点:
- 并发的控制,一般情况就是通过一个变量来判断是否超过限制,如果超过就需要等之前的请求完成之后再次发送请求;
- 每一个请求需要返回一个promise,以支持链式调用;
代码实现
function createFetch(limit) {
// [url, resolve, reject];
const queue = [];
// 当前请求的个数
let count = 0;
const request = () => {
// 判断一下queue,每次一个请求完成后,都会再次执行request
if (count < limit && queue.length) {
const [url, resolve, reject] = queue.shift();
// 实际运行是可以使用setTimeout模拟一下fetch
// finally默认返回then/catch的结果
fetch(url).finally(() => {
count--;
request();
}).then(resolve, reject);
// 执行一次,添加一次
count++;
}
}
return (url) => new Promise((resolve, reject) => {
queue.push([url, resolve, reject]);
request();
})
}
一个扩展写法为:合并 100ms 内发送的请求