我正在做一个个人项目,却被困在似乎是“基本”同步/异步Javascript问题上。
总结起来,我正在调用一个异步API,然后在屏幕上显示结果。
格式化后的期望结果是:“距Y的X公里处”,其中X是通过API计算并正确返回的,Y是地点的名称(未正确显示)。
这是我的代码,并附有一些注释以便更好地理解:
//loadedLandmarks.length is **always** between 1 and 3. No exception.
//In this sample, let's say we have 3 items in loadedLandmarks
for(var i = 0 ; i < loadedLandmarks.length ; i++)
{
var currentLandmarkName = loadedLandmarks[i].customInfo.Name;
landmarksName.push(loadedLandmarks[i].customInfo.Name);
//landmarkName contains the good names, for example : "My school", "My home", "My favorite nightclub" (here after 3 pass on the loop)
console.log(landmarksName);
//DisplayDistanceFromLandmarks is my method which calls the asynchronous API. It seems OK.
DisplayDistanceFromLandmarks(pos, i).then(function(response) {
//The response variable contains correct informations from the API
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var results = response.rows[0].elements;
//I explain this line below
console.log(loadedLandmarks)
//Then I'm formatting the result to display it on screen (I only paste here the interesting part)
distances += "<br />At " + results[0].distance.value + "kms from" + currentLandmarkName;
return distances;
}).done( /*some other things*/ );
显示的结果是:
距离[在此处插入LAST currentLandmarkName] 5公里
距[在此处插入LAST currentLandmarkName] 8.5公里
距离[在此处插入LAST currentLandmarkName]这里0.2公里
而应该是:
距离[在此处插入第一个currentLandmarkName] 5公里
距离[在此处插入SECOND currentLandmarkName] 8.5公里
距离[在此处插入第三个currentLandmarkName] 0.2公里
我不明白的是,当我写
console.log(loadedLandmarks)
时,数组的内容是正确的,其中loadedLandmarks[0].Name
=名字,loadedLandmarks[1].Name
=第二名字,依此类推。但是,
i
始终等于3,并且currentLandmarkName
始终等于最后一个地标名称。看来它们被覆盖了,我不明白为什么。
我是JS和异步问题的新手,有人可以向我解释为什么我会遇到这种行为,并且非常重要的是,如何纠正它?
最佳答案
var i = 0;
var DisplayDistance = function () {
var currentLandmarkName = loadedLandmarks[i].customInfo.Name;
landmarksName.push(loadedLandmarks[i].customInfo.Name);
//landmarkName contains the good names, for example : "My school", "My home", "My favorite nightclub" (here after 3 pass on the loop)
console.log(landmarksName);
//DisplayDistanceFromLandmarks is my method which calls the asynchronous API. It seems OK.
DisplayDistanceFromLandmarks(pos, i).then(function(response) {
//The response variable contains correct informations from the API
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var results = response.rows[0].elements;
//I explain this line below
console.log(loadedLandmarks)
//Then I'm formatting the result to display it on screen (I only paste here the interesting part)
distances += "<br />At " + results[0].distance.value + "kms from" + currentLandmarkName;
i++;
if (i < loadedLandmarks.length) {
DisplayDistance();
}
return distances;
}).done( /*some other things*/ );
}
DisplayDistance();