// 实现一个createRequest方法(假设浏览器允许无限多的并行请求),调用形式如下图,最后实现效果如图:
// ====>
// =====>
// =======>
// =====>
// ======>
// =====>
// ====>
// ====>
// 其中request函数的输入输出和fetch函数保持一致
以上是快手的面试题,pool表示请求池内最多可以容纳的请求个数,fn需要调用者传入,只有请求池内有完成的请求时,下一个请求才会发出去,以此类推,面试时写对了一半,现在又想了一下,写全了。 最关键的思路是else中的,内部的Promise函数调用了外部Promise函数的resolve方法,从而将结果传到外部。 在次记录一下。
function createRequest({ max, fn }) {
let curr = 0;
const allReq = [];
return (...params) => {
if (curr < max) {
// 小于max时,立即执行该请求
curr++;
return fn(...params).then(res => {
curr--;
const next = allReq.shift();
if (typeof next === 'function') {
next();
}
return res;
});
} else {
// 大于max时,将该请求缓存到数组中,等待被其他返回的请求触发调用
return new Promise((wrapperResolve, wrapperReject) => {
const delayedFn = () => {
fn(...params).then(res => {
wrapperResolve(res);
curr--;
const next = allReq.shift();
if (typeof next === 'function') {
next();
}
});
};
allReq.push(delayedFn);
})
}
}
}
const request = createRequest({
max: 3,
fn: n => fetch(`https://jsonplaceholder.typicode.com/todos/${n+1}`).then(res => res.json())
});
for (let i = 0; i < 100; i++) {
request(i).then(res => {
console.log(`${res.id} - ${res.title}`);
}).catch(err => {
console.log(err)
})
}
可以看到请求请求池内最多只有3个请求,只有当请求池内小于3个请求时,下一个请求才会被发出