按照顺序,依次完成异步请求
需要将多个异步请求的结果按照顺序输出。
给定一个数组list,数组中的每一项包含id、name和delay属性。需要按照idList中的顺序,查找相应id对应的name和delay,在延迟delay秒后,输出name。
const list = [
{id: 'id_a', name: 'foo', delay: 2},
{id: 'id_b', name: 'bar', delay: 4},
{id: 'id_c', name: 'baz', delay: 1},
{id: 'id_x', name: 'str_x', delay: 3}
];
const idList =['id_b', 'id_x', 'id_a', 'id_c'];
这可以看作是每次只允许一个并发请求的情况。
function inOrder(list, idList){
// 通过一个循环将promise串起来
const recursion = (id, prev) => {
let {name, delay} = list.find(v => v.id === id);
// 由于需要使用到setTimeout,用Promise包一层
return new Promise((resolve, reject) => {
setTimeout(()=>{
console.log(prev ? prev + '-'+ name: name);
resolve(prev ? prev + '-'+ name: name);
}, delay * 1000)
}).then((val) => {
// 判断当前数组是否遍历完成了,没有完成传递数组首位参数调用循环
if(idList.length){
return recursion(idList.shift(), val);
}
// 数组遍历完成后,直接传递最终结果
return val;
})
}
// 可以看作是并发请求数为1的情况,直接调用循环
return recursion(idList.shift(), '');
}
inOrder(list, idList).then((val) => {
console.log(val);
})
在最短的时间内,完成所有异步请求?如果有最大并发数限制呢?
假设加法需要通过异步请求完成,如何在最快的时间内计算出一个数组中数的总和?
在不考虑并发数限制的情况下,发起尽可能多的异步请求,将每次异步请求后的结果放回数组中,如果数组中的数会大于2个,就接着再发起请求。直到数组中只剩下一个数时,这个数就是计算的总和了。最后用一个Promise.all等待并发请求数组中的请求都执行完。
如果有并发数的限制,就是在while(idList.length >= 2)中再添加一个限制的判断,如while(idList.length >= 2 && limit--)。
function request(num1, num2){
return new Promise((res, rej) => {
setTimeout(()=>{
res(num1 + num2);
}, 1000)
})
}
const idList =[1,2,3,4,5,6,7];
function calc(){
const recursion = (num1, num2) => {
// 调用加法请求
return request(num1, num2).then((val) => {
// 将请求返回的结果放回数组中,还需要跟数组中的其他数做加法
idList.push(val);
}).then(() => {
// 如果当前数组中的数大于2个时,再次调用递归函数处理数组中的最后两个数
if(idList.length >= 2){
return recursion(idList.pop(), idList.pop());
}else{
// 否则的话返回最后的结果
return idList;
}
})
}
// 用来存储所有的异步请求
let asyncList = [];
// 当数组中的数大于2个时,调用递归函数处理目前数组中的最后两个数,并将这两个数移出数组
while(idList.length >= 2){
asyncList.push(recursion(idList.pop(), idList.pop()));
}
// 利用Promise.all等待异步请求数组中的请求都执行完
return Promise.all(asyncList);
}
calc().then((val) => console.log(val))