麦田里的POLO桔 2022-01-26 10:12 采纳率: 0%
浏览 149

map中使用await为什么会失效?

问题发生的场景:页面渲染时,会加载一个n行的列表,列表每一行对应一组数据,一组数据由一个请求获得。我们需要将请求获取到的数据按照一定顺序显示到页面上

下面先看一下数据大致的请求与存储方式:

dataSource = [obj1, obj2, objn];
 
getData = (dataSource) => {
  let selectArr = [];
  let { title } = this.props;
 
  _.map(dataSource, async (item, index) => {
 
    // 请求数据
    await getBasicPlans(title, item.id).then(data => {
      // 将数据按照请求时的顺序保存进数组(optionsArr是一个数组,里面保存着option中的一条条数据)
      selectArr.splice(index, 0, data.optionsArr);
      this.setState({ selectArr });
    })

  })
}

可以看到,我们将数据存储进数组时,使用了遍历时的index,并且还有await进行同步化的处理。按理来说,请求完了第一条数据才会请求请求第二条数据,这样一来,splice中的index就是从0→1→2依次增大,那么selectArr中存储的数据就是有序的

但结果确是selectArr中存储的数据是无序的

我们在.then中打印index来看一下:

img

可以看到,并没有按照我们预想的那样按照顺序将index打印出来

  1. 也就是说map种使用的await并没有生效,为什么呢?
  2. 看到很多博主说for of使用了迭代器,可以解决这一问题,但是一个朋友仅仅将上面的map换成了最基本的for循环就实现了,为什么最基本的for循环就能解决这一问题呢?
  • 写回答

4条回答 默认 最新

  • 拖下去砍了 2022-01-26 10:45
    关注

    map/forEach内部使用了while结合callback方式来执行函数,await不会等待callback的执行
    可以这样写

    await Promise.all(
      a.map(dataSource, (item, index) => {
        // 请求数据
        await getBasicPlans(title, item.id).then(data => {
          // 将数据按照请求时的顺序保存进数组(optionsArr是一个数组,里面保存着option中的一条条数据)
          selectArr.splice(index, 0, data.optionsArr);
          this.setState({ selectArr });
      })
        })
    );
    

    这样写一点好处都没有,会导致速度慢,影响客户体验

    评论

报告相同问题?

问题事件

  • 修改了问题 1月26日
  • 创建了问题 1月26日