循环遍历数组异步更改不同索引的值

时间:2016-12-21 23:01:02

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

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

以下是代码

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。这些是为了表明变量如何在不应该​​变化的地方发生变化。每次在声明之前和之后显示有问题的对象。它还会在执行时显示地址键和充电器密钥。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:3)

我认为问题出在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 };
});

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

Modified fiddle(使用第一个解决方案)

相关问题