美文网首页
Vue---循环执行异步请求导致原数组顺序变化bug

Vue---循环执行异步请求导致原数组顺序变化bug

作者: 二营长家的张大炮 | 来源:发表于2019-12-09 16:47 被阅读0次

最近写项目的时候,碰到个问题:

请求的数组中某个字段需要执行请求进行二次渲染,在遍历原数组执行异步请求的时候,碰到了两个问题,第二个问题是因为第一个问题解决之后出现的新问题。。。。

第一个问题:数组遍历执行异步请求后通过push到新数组导致顺序可能会发生改变


image.png

第二个问题:循环遍历未结束时,新数组就已经赋值给原数组了,导致控制台报某个字段undefined

解决第一个问题的办法:
在循环原数组进行遍历的时候,可以携带索引,然后将请求结果赋值新数组的时候按照索引进行插入,这样新数组顺序跟原数组顺序就是一样的了
再通过索引改变新数组的时候可能存在个问题:
Vue官网上的:

由于 JavaScript 的限制,Vue 不能检测以下数组的变动:
1.当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
2.当你修改数组的长度时,例如:vm.items.length = newLength
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将在响应式系统内触发状态更新:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:

vm.$set(vm.items, indexOfItem, newValue)

第二个问题:因为js是单线程,执行遍历的时候下面的赋值操作可能就已经结束了,然后新数组在遍历完成之前都是空数组,这才导致了某个字段取不到。
解决办法:在执行遍历前声明一个索引,每执行一次遍历结束索引加1,如果索引等于原数组长度,说明执行完成,此时在进行赋值即可

  private getDataSourceFilter(dataSource: ResourceInfo[]) {
    let newDataSource: ResourceInfo[] = [];
    let idx = 0;
    dataSource.forEach(async (item: ResourceInfo, index: number) => {
      let areaName = "";
      const PromiseAll = [
        HttpRequest.getAreaInfoById({ areaId: item.cityId }),
        HttpRequest.getAreaInfoById({ areaId: item.countyId })
      ];
      const resAll = await Promise.all(PromiseAll);
      if (resAll) {
        resAll.forEach((resItem: any) => {
          if (resItem && resItem.data) {
            areaName += resItem.data.areaName;
          } else {
            areaName += "";
          }
        });
        const newItem = Object.assign(item, { areaName });
        // newDataSource.push(newItem);
        /**
         * Vue.set
         */
        Vue.set(newDataSource, index, newItem);
        idx += 1;
        if (dataSource.length === idx) {
          this.dataSource = newDataSource;
          this.loading = false;
        }
      }
    });

相关文章

网友评论

      本文标题:Vue---循环执行异步请求导致原数组顺序变化bug

      本文链接:https://www.haomeiwen.com/subject/iwxigctx.html