JS Array.map方法内异步方法无法同步执行

导读:本篇文章讲解 JS Array.map方法内异步方法无法同步执行,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

问题:

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)
    })
    return 10
  })
  console.log(res)
})()

使用node执行一下发现

在这里插入图片描述

解决

1.使用for..of或者其他循环替代

因为我们无法改变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)
    })
    return 10
}));
console.log(res)

原因剖析

map函数的原理是:

循环数组,获取每项数组对应的内容,

调用map函数传入的方法,获取数组的新内容,

将新内容push到新数组,最后返回。

map函数是同步执行的,所以循环每一项时,到给新数组值时,都是同步操作。

上面返回数组中都是Promise对象,因为他们还没执行完成就赋值了。

为了更加了解为什么,我们可以自己写一个map方法。

Array.prototype.mymap = async function (fun) {
  let ret = []
  for(let item of this) {
    // 遍历
    // 等待传入的异步执行完成再push
    item = await fun(item)
    ret.push(item)
  }
  // 全部完成
  return ret
};

(async () => {
  let arr1 = [1,2,3,4,5]
  let res = await arr1.mymap(async (item)=>{
    // 异步操作
    await new Promise(resolve=>{
        setTimeout(() => {
          console.log(item + '内结束');
          resolve();
        }, 2000)
    })
    return 10
  })

  console.log(res)
})()

总结

要运用最合适的方法处理最合适的问题,才能达到事半功倍~~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/102156.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!