如何使这个方法异步?

时间:2017-09-11 09:10:10

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

我正在编写一个使用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");
            }
        );
}

1 个答案:

答案 0 :(得分:0)

你可以把它作为一个承诺包装起来。类似的东西:

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或generator函数。然后你可以这样做:

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"))