Javascript 异步对象操作

Javascript 异步对象操作,javascript,angular,asynchronous,callback,Javascript,Angular,Asynchronous,Callback,我有一个对象要传递给函数并进行操作,名为spots 我的setdistance函数就是这样做的 在函数之后,我将console.log如下操作的值console.log('DistanceFrom Set.'+distSetSpots[0].DistanceFrom)&该值似乎尚未更改 奇怪的是,如果我console.log像这样的整个对象console.log(distSetSpots)&通过chrome开发工具,而不是通过编程,它实际上会显示被操纵的值 这让我很困惑。。有人能解释一下这里发生

我有一个对象要传递给函数并进行操作,名为
spots

我的
setdistance
函数就是这样做的

在函数之后,我将
console.log
如下操作的值
console.log('DistanceFrom Set.'+distSetSpots[0].DistanceFrom)&该值似乎尚未更改

奇怪的是,如果我
console.log
像这样的整个对象
console.log(distSetSpots)&通过chrome开发工具,而不是通过编程,它实际上会显示被操纵的值

这让我很困惑。。有人能解释一下这里发生了什么吗?完整的相关代码如下:

    // Get a copy of the Spots data in spots.json
this.sds.fetchData( (spots) => {
  // Get distance inbetween each spot & the user's location
    this.lcs.setDistances(spots, (distSetSpots) => {
      console.log(distSetSpots);
      console.log('DistanceFrom Set. ' + distSetSpots[0].distanceFrom);
      // 'Filter' spots (set 'pts' to null) that exceed max distance
      this.filterFarSpots(distSetSpots, (filteredSpots) => {
        // Find matched target species in spots & assign pts
        this.findTargetSpecies(filteredSpots, (prefTargSpots) => {
        });
      });
    });
  }
);
(resp, status) => {
        spots[this.count].distanceFrom = (resp.rows[0].elements[0].distance.value / 1000).toFixed(1);
        if ((this.count + 1) < spots.length) {
          this.count++;
          this.setDistances(spots, callback);
        } else {
          this.count = 0;
          callback(spots);
        }
    });
设置距离功能:

setDistances(spots, callback) {
  const posRef = this.posObject;
  for (let i = 0; i < spots.length; i++) {
    const origin = new google.maps.LatLng(posRef.pos.coords.latitude, posRef.pos.coords.longitude);
    const destination = new google.maps.LatLng(spots[i].coords[0], spots[i].coords[1]);
    const service = new google.maps.DistanceMatrixService();
    service.getDistanceMatrix({
      origins: [origin],
      destinations: [destination],
      travelMode: 'DRIVING',
    }, (resp, status) => {
      spots[i].distanceFrom = (resp.rows[0].elements[0].distance.value / 1000).toFixed(1);
    });
  }
  callback(spots);
}
setdistance(点、回调){
const posRef=this.posObject;
for(设i=0;i{
点[i].distanceFrom=(相应行[0].elements[0].distance.value/1000.toFixed(1);
});
}
回收(点);
}

试着让你
回叫(点)
打电话到这个地方:

...
service.getDistanceMatrix({
  origins: [origin],
  destinations: [destination],
  travelMode: 'DRIVING',
}, (resp, status) => {
  spots[i].distanceFrom = (resp.rows[0].elements[0].distance.value / 1000).toFixed(1);
  callback(spots);
});

问题是回调(..)是在映射回调之前执行的。因此,在调用
callback(spots)
时,
spots
数据尚未设置,正如注释中所述,我的
setdistance
函数在出现任何响应之前使用了
callback
。多亏Paulpro清理了我的
控制台.log
困惑。以下是我如何着手解决我的问题:

我删除了通过
getDistanceMatrix
发出请求的
for循环
,并将其替换为一个自调用函数调用,以及一个条件语句&a
count
变量,以跟踪每个请求,当所有请求完成时,该变量也会调用
回调
。代码如下:

    // Get a copy of the Spots data in spots.json
this.sds.fetchData( (spots) => {
  // Get distance inbetween each spot & the user's location
    this.lcs.setDistances(spots, (distSetSpots) => {
      console.log(distSetSpots);
      console.log('DistanceFrom Set. ' + distSetSpots[0].distanceFrom);
      // 'Filter' spots (set 'pts' to null) that exceed max distance
      this.filterFarSpots(distSetSpots, (filteredSpots) => {
        // Find matched target species in spots & assign pts
        this.findTargetSpecies(filteredSpots, (prefTargSpots) => {
        });
      });
    });
  }
);
(resp, status) => {
        spots[this.count].distanceFrom = (resp.rows[0].elements[0].distance.value / 1000).toFixed(1);
        if ((this.count + 1) < spots.length) {
          this.count++;
          this.setDistances(spots, callback);
        } else {
          this.count = 0;
          callback(spots);
        }
    });
(响应,状态)=>{
spots[this.count].distanceFrom=(相应行[0]。元素[0]。distance.value/1000)。toFixed(1);
如果((this.count+1)
可能需要查看您的
setdistance
代码。您正在调用
回调(spots)设置距离
中进行编码。当您记录整个对象时,Chrome控制台会显示正确的内容,因为它会显示您在控制台中展开对象时的对象状态,而不是记录对象时的状态。访问距离矩阵服务是异步的,因此您需要通过一种或两种方式来处理此问题。一次处理每个请求,或者一次处理所有请求。您的for循环当前会立即处理它们,然后调用回调,而不会真正等待响应。很遗憾,第一次响应后将立即处理。