数组的异步循环遍历方法 - Luomusha/blog GitHub Wiki
如果说,请写出遍历数组的方法,大多数前端不屑一顾的列举
const array = [1,2,3,4,5,6,7,8];
array.forEach((num:number) => {
console.log(num)
})
const array = [1,2,3,4,5,6,7,8];
for(let i=0;i<array.length;i++){
console.log(array[i])
}异步遍历
但是如果循环项是异步的呢? 比如有一个url列表,要求遍历列表,依次请求数据,累加响应的字符串长度?
const urlList = [
"https://www.baidu.com",
"https://www.sina.com",
"https://www.qq.com",
"https://www.bing.com",
]
const countString = async (url:string):Promise<number> => {
const res = await fetch(url)
const resData = await res.text();
return resData.length
}给30秒考虑
...
让我们先想当然的套用一下上面的方法试试?
let count = 0
urlList.forEach(async (url:string) => {
console.log("start")
count += await countString(url)
console.log("end", count)
});结果为:
start
start
start
start
end 227
end 102012
end 488005
end 111462
从结果上看没什么问题。 但是我们仔细观察后发现,程序是一次性发送所有请求,不管响应如何的。 如果同时有成百上千的请求同时发送,就会大量占用内存,造成电脑卡司。
所以能不能有办法依次发送请求,等上一个请求响应后再发送第二个呢? 思考三十秒
直接上答案:递归。
递归应该是变成里面最复杂的逻辑之一。大家要注意递归和遍历的区别,体会递归和遍历的区别。 过程略,直接上代码
let count = 0
let index = 0;
const countOneByOne = async (index:number) =>{
console.log("start")
const url = urlList[index];
count += await countString(url)
console.log("end", count)
if(index + 1 < urlList.length){
await countOneByOne(index + 1)
}
};
countOneByOne(0)结果如下:
start
end 227
start
end 488233
start
end 590217
start
end 701648
递归太难了。有没有简单的办法呢? 有!
请出我们的主角,上代码
let count = 0;
const countAsync = async () => {
for await (const url of urlList) {
console.log("start")
count += await countString(url)
console.log("end", count)
}
}
countAsync()结果如下:
start
end 227
start
end 488242
start
end 590226
start
end 701688