【问题标题】:Looping through an array asynchronously changes values for different indexes遍历数组异步更改不同索引的值
【发布时间】:2016-12-21 23:01:02
【问题描述】:

我有一个异步循环,它发送索引值来保存结果。但是,由于某种原因,该项目第一次循环时,它会正确记录该值。第二次循环。它会更改第一个循环中的值和第二个循环中的值,依此类推。根据输入,它似乎不一致地执行此操作。

下面是代码

promises[address_key] = addresses[address_key].nearest.map(function(currentValue, charger_key) { // This loops through items creating promises
  return new Promise(function(resolve) {
    addresses[address_key].nearest[charger_key].directions = get_driving_directions(addresses[address_key].nearest[charger_key]);
    addresses[address_key].nearest[charger_key].map_img = get_static_map_url(addresses[address_key].nearest[charger_key]);
    get_driving_distance(address_key, charger_key, resolve); // this calls the get_driving_distance function below
  });
});
/* more code here */
// Calls distance matrix from Google's api. 
function get_driving_distance(address_key, charger_key, resolve) {
    var distance_matrix = new google.maps.DistanceMatrixService();
    distance_matrix.getDistanceMatrix( // calls distance matrix in Google API
      {
        origins: [addresses[address_key].address],
        destinations: [new google.maps.LatLng(addresses[address_key].nearest[charger_key].latitude, addresses[address_key].nearest[charger_key].longitude)],
        unitSystem: google.maps.UnitSystem.IMPERIAL,
        travelMode: 'DRIVING'
      }, process_distance_matrix(address_key, charger_key, resolve) // calls process_distance_matrix function sending over variables necessary.
    );
  }
  // processes data from the distance matrix in the function get_driving_distance

function process_distance_matrix(address_key, charger_key, callback) {
  return function(response, status) {
    if (response.rows[0].elements[0].status == 'OK') {
      console.log("response", response, 'status', status, 'address_key', address_key, 'charger_key', charger_key);
      console.log("Records before:", addresses[0].nearest[0].distance, response.rows[0].elements[0].distance.text, 'address_key', address_key, 'charger_key', charger_key);
      // Update the global variable with the distance data. This is recording data in wrong fields.
      addresses[address_key].nearest[charger_key].distance = {
        'text': response.rows[0].elements[0].distance.text,
        'number': response.rows[0].elements[0].distance.value / 1609.344,
        'over_limit': (max_driving_distance ? (response.rows[0].elements[0].distance.value / 1609.344 > max_driving_distance) : false)
      };
      console.log("Records after:", addresses[0].nearest[0].distance, response.rows[0].elements[0].distance.text, 'address_key', address_key, 'charger_key', charger_key);
    } else {
      display_error(address_key + ') ' + addresses[address_key].address + ' - Error getting driving distance');
      addresses[address_key].errors.push('Error getting driving distance');
      progress_status.error++;
    }
    callback();
  }
}

剩下的代码太多了就不贴了,所以这里是剩下的代码的链接:https://jsfiddle.net/RobertoMejia/cqyyLh27/

原来的循环是第 68 行的一个 for 循环。这个循环遍历地址并传递 address_key 来引用全局对象。

第 183 行有第二个循环。它是一个 .map 循环。这会通过充电器运行,并通过 Charger_key 来引用全局对象。

注意函数中间的console.logs。这些是为了显示变量如何改变它不应该改变的地方。每次声明前后都显示有问题的对象。它还显示了执行时的地址密钥和充电器密钥。

任何帮助将不胜感激。

【问题讨论】:

  • 这段代码的循环在哪里?
  • 有太多的代码在试图找出问题所在,但我敢打赌它类似于stackoverflow.com/questions/1451009/…
  • @Barmar 是的,这有点复杂。循环在第 183 到 189 行。
  • 我在那里看不到循环。没有forwhile 声明,也没有对forEach() 的调用。
  • 啊,现在我看到了对.map()的调用。

标签: javascript loops asynchronous google-maps-api-3


【解决方案1】:

我认为问题出在process_addresses

addresses[address_key].nearest = charger_data.sort( sort_by_closest( addresses[address_key].geo ) );
    // Takes the top results based on the number of results wanted.
addresses[address_key].nearest = addresses[address_key].nearest.slice(0, $('#number_of_results').val() );

如果同一个充电器靠近多个地址,则该充电器将位于所有地址的nearest 数组中。因此,当您从一个地址向充电器添加行车路线时,您将替换上一个地址的路线。

有两种解决方案:

最简单的方法是在将充电器对象放入nearest 数组之前对其进行克隆。

addresses[address_key].nearest = addresses[address_key].nearest.slice(0, $('#number_of_results').val()).map(function(charger) {
    return $.extend({}, charger);
});

另一种方法是使用不同的对象来保存方向,并使充电器成为它的属性:

addresses[address_key].nearest = addresses[address_key].nearest.slice(0, $('#number_of_results').val()).map(function(charger) {
    return { charger: charger };
});

这是惠勒著名格言的一个应用:“计算机科学中的所有问题都可以通过另一个间接层次来解决”

Modified fiddle(使用第一种方案)

【讨论】:

  • 谢谢你,巴尔玛!那行得通!你是代号绝地!!!我将帮助宣传您的惊人技能和您今天所做的好事!再次感谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
  • 2017-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
相关资源
最近更新 更多