如何使这种方法异步? [英] How to make this method asynchronous?
问题描述
我正在编写一个使用google javascript api的应用程序;一切都很出色,直到我想添加反向地理编码。
我的问题如下:我正在调用下面的这个方法, geocodeLatLng,每条记录至少一条记录。
我已经放入了痕迹,并将其打印出来,如下所示:
坐标:-33.88091325759888, 18.635687828063965
坐标:-33.874990940093994,18.639239072799683
坐标:-33.90454888343811,18.627684116363525
坐标:-33.849005699157715,18.63781213760376
坐标:-33.85634422302246,18.639850616455078
坐标:-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 =结果[0] .formatted_address;
id_address_map.set(callID,returnString);
} else {
returnString ='地址未知';
id_address_map.set callID,returnString);
}
} else {
returnString ='Geocoder失败,原因是:'+ status;
id_address_map.set(callID,returnString);
}
});
$ / code>
建议的解决方案:
函数asyncGeoCode(callID,lat,lng){
var returnString =;
var latlng = {lat,lng};
console.log(coordinates:+ lat +,+ lng);
var geocoder = new google.maps.Geocoder;
返回新的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(address is已知);
},
函数(错误){
console.log(未知地址);
}
);
诺言。例如:
函数asyncGeoCode(callID,lat,lng){
// ...
返回新的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(所有调用一个接一个地完成))
如果您可以使用es7 async / await:
//在某些异步函数或异步IIFE
中等待asyncGeoCode(foo,1,2);
等待asyncGeoCode(bar,123,321);
如果您遇到es5并且无法使用异步/等待或生成器函数。那么你可以做这样的事情:
pre $函数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))
I am writing an app that uses the google javascript api; Everything is working splendidly, until I want to add the reverse geo-coding.
The problem that I have is as follows: I am making a call to this method below, geocodeLatLng, per record, for a minimum of one record.
I have put traces in, and the it will print out as follows:
coordinates: -33.88091325759888, 18.635687828063965
coordinates: -33.874990940093994, 18.639239072799683
coordinates: -33.90454888343811, 18.627684116363525
coordinates: -33.849005699157715, 18.63781213760376
coordinates: -33.85634422302246, 18.639850616455078
then after this, it prints out:
returned status is: OK (x5)
I would really want each call to the geocodeLatLng method to be completed in its entirety, before the next one attempts to start processing. How do I accomplish this?
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);
}
});
}
Proposed solution:
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")}
});
});
}
}
and when it is called:
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");
}
);
}
you could wrap it as a promise. something like:
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")}
}
})
}
and use it like
asyncGeoCode("foo", 1, 2)
.then(resultsFormFirsCall => asyncGeoCode("bar", 123, 321))
...
.then(() => console.log("all calls done one after the other"))
and if you can use es7 async/await:
// in some async function or an async IIFE
await asyncGeoCode("foo", 1, 2);
await asyncGeoCode("bar", 123, 321);
in case you are stuck with es5 and can not use async/await or generator functions. then you could do something like:
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"))
这篇关于如何使这种方法异步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!