JSArray.map⽅法内异步⽅法⽆法同步执⾏
问题:
JS Array.map⽅法内异步⽅法⽆法同步执⾏
场景:
我们在使⽤map来设置每⼀项值的时候,涉及到异步操作,就会出现问题。
按照常规,重现出⼀种情形。
假设我要使⽤map对每⼀项值进⾏操作,其中涉及到异步操作(此处使⽤演⽰来模拟),在简短延时后将值设置为10。我们理想中ret的值是[10,10,10,10,10]
(async()=>{
let arr =[1,2,3,4,5]
let res =await arr.map(async(item)=>{
console.log(item+'执⾏')
// map并发执⾏
await new Promise(resolve=>{
setTimeout(()=>{
console.log(item+'结束');
resolve();
},2000)
})
return10
})
console.log(res)
})()
使⽤node执⾏⼀下发现
解决
1.使⽤f或者其他循环替代
因为我们⽆法改变map函数内部的代码,使⽤Promise同步化异步操作。
所以我们只能⾃⼰遍历出所有内容,进⾏逐⼀操作。
2.使⽤promise.all
let arr1 =[1,2,3,4,5]
let res =await Promise.all(arr.map(async(item)=>{
await new Promise(resolve=>{
setTimeout(()=>{
console.log(item +'内结束');
resolve();
},2000)
})
return10
}));
console.log(res)
原因剖析
map函数的原理是:
循环数组,获取每项数组对应的内容,
调⽤map函数传⼊的⽅法,获取数组的新内容,
将新内容push到新数组,最后返回。
map函数是同步执⾏的,所以循环每⼀项时,到给新数组值时,都是同步操作。上⾯返回数组中都是Promise对象,因为他们还没执⾏完成就赋值了。
为了更加了解为什么,我们可以⾃⼰写⼀个map⽅法。
ap =async function(fun){
let ret =[]
for(let item of this){
// 遍历
// 等待传⼊的异步执⾏完成再push
item =await fun(item)
ret.push(item)
}
// 全部完成
return ret
};js数组方法总结
(async()=>{
let arr1 =[1,2,3,4,5]
let res =ap(async(item)=>{
// 异步操作
await new Promise(resolve=>{
setTimeout(()=>{
console.log(item +'内结束');
resolve();
},2000)
})
return10
})
console.log(res)
})()
总结
要运⽤最合适的⽅法处理最合适的问题,才能达到事半功倍~~

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。