首页 > 解决方案 > vue中如何让阻塞代码变成非阻塞?

问题描述

我正在构建一个 vue 应用程序,它使用遗传算法来寻找最短路径。我使用 google maps api 来获取距离矩阵,并且为了简单起见还使用 vue2-google-maps 包。我的代码将 api 获取的数据存储到数组中,假设我有 7 个位置,当从谷歌获取路径 A 到 B 的距离时,我将其存储在数组中。因此,如果在下一条路线中有路径 A 到 B,我不需要再次发出 API 请求。示例:

#Population 1
Route 1 : 1-2-3-4-5-6-7 = 10km //total distance of route 1
Route 2 : 7-2-1-3-5-4-6 = 20km
Route 3 : 1-2-6-3-4-7-6 = 15km
...

这就是我存储从google api调用的路径的方式。

savedNodePath={1:
                 {2:1.2km}
                 {4:2km}
                   ...
                          }

我希望创建这样的矩阵数组:

从到 1 2 3 4 5
1 0 3公里 1.2公里 4公里 2公里
2 5.2公里 0 6公里 2公里 11公里
3 8公里 5公里 0 4公里 2公里

话虽如此,如果我有 7 个位置,我只需要从谷歌地图获取数据大约 49 次。问题来了。当它仍然从谷歌调用 API 时,我的页面仍然是响应式的,它响应式地更新从路径 1 到另一个的路径距离。但是当它不再调用 api 时,因为所有可能的路径都存储在我的数组中。开始“冻结”的过程,经过一段时间后,所有路线距离立即被填满。

这就是我计算一个点到另一个点的距离的方法:

caclDistance: async function (a, b) {
  
    //if path from A isnt called yet.
    if (this.savedNodePath[a] === undefined) {
      let dist = await this.getDistanceApi(a, b).then((res) => {
        return res.rows[0].elements[0].distance.value;
      });

      this.savedNodePath[a] = { [b]: dist};
      this.$set(this.savedMiniRoute, a, this.savedNodePath[b]);
      return this.savedNodePath[a][b];
    }
    //if path A to B are already called
    else if (this.savedNodePath[a][b]) {
      //I think this is the problem
      return this.savedNodePath[a][b];
    }
    //if path from A exist, but to B hasnt called yet
    else if (this.savedNodePath[a]) {
      let dist = await this.getDistanceApi(a, b).then((res) => {
        return res.rows[0].elements[0].distance.value;
      });

      this.savedMiniRoute[a][b] = dist;
      this.$set(this.savedMiniRoute[a], b, dist);
    }
},

这就是我计算路线总路径距离的方式:

calcRoute: async function () {
  for (const i in this.route) {
    let sum = 0;
    for (let j = 1; j < this.route[i].length; s++) {
      let a = this.route[i][j - 1];
      let b = this.route[i][j];
      let dist = await this.calcDistance(a, b).then((r) => {
        return r;
      });
      sum += dist;
    }
    if (sum < this.bestDist) {
      this.bestDist = sum;
      this.$set(this.bestPop, 1, this.population[i]);
    }
    this.$set(this.distance, i, sum);
  }
},

我一直在尝试将我认为导致问题的代码包装在一个承诺中,使用 nextTick,使用 setTimeout,它们都不起作用。当它不再获取 google apis 时它仍然冻结。知道如何解决这个问题吗?另外,是否有任何方法可以为此制作加载动画?

PS:我还是 javascript 的初学者,我很抱歉英语不好和我的代码不好 :)

谢谢!

标签: javascriptvue.js

解决方案


推荐阅读