gpt4 book ai didi

javascript - 如何在循环调用时显示 JS 异步结果?

转载 作者:行者123 更新时间:2023-12-02 15:51:04 27 4
gpt4 key购买 nike

我正在开发一个个人项目,但我遇到了一个“基本”同步/异步 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*/ );

显示的结果是:

At 5 kms from [insert here the LAST currentLandmarkName]
At 8.5 kms from [insert here the LAST currentLandmarkName]
At 0.2 kms from [insert here the LAST currentLandmarkName]

其实应该是:

At 5 kms from [insert here the FIRST currentLandmarkName]
At 8.5 kms from [insert here the SECOND currentLandmarkName]
At 0.2 kms from [insert here the THIRD currentLandmarkName]

我不明白的是,当我编写console.log(loadedLandmarks)时,数组的内容是正确的,loadedLandmarks[0].Name = 第一个名字,loadedLandmarks[1].Name = 第二个名字等等。但是,i 始终等于 3,currentLandmarkName 始终等于最后一个地标名称。
它们似乎被覆盖了,我不明白为什么。


我对 JS 和异步问题非常陌生,有人可以解释一下为什么我会遇到这种行为,而且非常重要的是,如何纠正它?

最佳答案

此方法 DisplayDistanceFromLandmarks 是异步的,这意味着它不会阻止其余代码的执行。因此,当您在回调中形成 html 字符串 distances 时,如下所示:

distances += "<br />At " + results[0].distance.value + "kms from" + currentLandmarkName;

for 循环已经结束,回调函数调用已排队,稍后返回其值。回调函数的作用域中没有 currentLandmarkName,因为它的定义如下

var currentLandmarkName = loadedLandmarks[i].customInfo.Name;

我觉得你可以做两件事:

  1. 将变量 currentLandmarkName 传递到 DisplayDistanceFromLandmarks 方法中,从而将其纳入范围内。
  2. 您还可以尝试使用 while 循环并递增计数器,即仅在回调内的变量 i。这样你就可以强制异步行为同步。因此,循环的下一次迭代只会在 Promise 得到解决并且回调被评估之后才会发生。

我遇到了一篇非常好的文章,它解释了 javascript 的异步行为和闭包的概念。您可能想读一下 http://www.javascriptissexy.com/understand-javascript-closures-with-ease/

希望它能让您朝着正确的方向开始。干杯!

关于javascript - 如何在循环调用时显示 JS 异步结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31849205/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com