我有一个异步循环,它发送索引值以保存结果。但是,出于某种原因,第一次此项循环时,它会正确记录该值。第二次循环。它会改变第一个循环中的值和第二个循环中的值,依此类推。根据输入的不同,它似乎不一致。
以下是代码
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。这些是为了表明变量如何在不应该变化的地方发生变化。每次在声明之前和之后显示有问题的对象。它还会在执行时显示地址键和充电器密钥。
任何帮助都将不胜感激。
答案 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(使用第一个解决方案)