【问题标题】:How to make this method asynchronous?如何使此方法异步?
【发布时间】:2017-09-11 09:10:10
【问题描述】:

我正在编写一个使用 google javascript api 的应用程序;一切都很好,直到我想添加反向地理编码。

我遇到的问题如下:我正在调用下面的这个方法,geocodeLatLng,每条记录,至少一条记录。

我已经把痕迹放进去,它会打印出来如下:

坐标:-33.88091325759888, 18.635687828063965

坐标:-33.874990940093994, 18.639239072799683

坐标:-33.90454888343811, 18.627684116363525

坐标:-33.849005699157715, 18.63781213760376

坐标:-33.85634422302246, 18.639850616455078

然后在此之后,它会打印出来:

返回状态为:OK (x5)

我真的希望对 geocodeLatLng 方法的每次调用在下一次尝试开始处理之前完成。我该如何做到这一点?

function geocodeLatLng(callID, lat, lng) {
    var returnString = "";
    var latlng = {lat,lng};
    console.log("coordinates: " + lat + ", " + lng);
    var geocoder = new google.maps.Geocoder;

    geocoder.geocode({'location': latlng}, function(results, status) {
        console.log("returned status is: " + status);
        if (status === 'OK') {
            if (results[0]) {
                var marker = new google.maps.Marker({position: latlng,});
                returnString =  results[0].formatted_address;
                id_address_map.set(callID, returnString);

            } else {
                returnString = 'Address unknown';
                id_address_map.set(callID, returnString);
            }
        } else {
            returnString = 'Geocoder failed due to: ' + status;
            id_address_map.set(callID, returnString);
        }   
    }); 
}

建议的解决方案:

function asyncGeoCode(callID, lat, lng) {
    var returnString = "";
    var latlng = {lat,lng};
    console.log("coordinates: " + lat + ", " + lng);
    var geocoder = new google.maps.Geocoder;

      return new Promise((resolve, reject) => {


        geocoder.geocode({'location': latlng}, function(results, status) {
            if (status === "OK") { resolve(results);}
            else {reject("some error msg")}
        });
    });
}

}

以及何时调用:

for(var i = 0; i< markers.length; i++) {
    asyncGeoCode(markers[i].CallID, markers[i].Latitude, markers[i].Longitude)
        .then(
            function() {
                console.log("the address is known");
            },

            function(err) {
                console.log("unknown address");
            }
        );
}

【问题讨论】:

  • 你是在节点环境下运行还是在浏览器上运行?你是否使用任何转译器,例如通天塔?

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


【解决方案1】:

你可以把它包装成一个承诺。类似:

function asyncGeoCode(callID, lat, lng) {
  // ...
  return new Promise((resolve, reject)) => {
    geocoder.geocode({'location': latlng}, function(results, status) {
      if (status === "OK") { resolve(results);}
      else {reject("some error msg")}
    }
  })

}

并像使用它

asyncGeoCode("foo", 1, 2)
  .then(resultsFormFirsCall => asyncGeoCode("bar", 123, 321))
  ...
  .then(() => console.log("all calls done one after the other"))

如果你可以使用 es7 async/await:

// in some async function or an async IIFE 
await asyncGeoCode("foo", 1, 2);
await asyncGeoCode("bar", 123, 321);

如果你被 es5 卡住并且不能使用 async/await 或生成器函数。那么你可以这样做:

function asyncRecursiveGeoCall(index) {
  return asyncGeoCode(/*info from markers[index]*/)
    .then(function() {
      if (index < markers.length - 1) {return asyncRecursiveGeoCall(index + 1)}
      else {return Promise.resolve()}
    })
}
asyncRecursiveGeoCall(0).then(() => console.log("all done"))

【讨论】:

  • 嗨@user2520818。我已将您的建议与 MDN 一起用于设置建议的解决方案。不过,我无法按照您建议的方式调用该方法。有什么变化你可以再看看吗?交易量 H
  • 使用 Promises.All 而不是 then 可能会更好。然后 。那么呢?
  • Promise.all 的问题是它们是并行运行的。我认为他们希望他们一个接一个
  • 我在浏览器中运行它;我没有任何转译器
  • 知道所有通话结束的时间重要吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 2017-03-06
相关资源
最近更新 更多