简体   繁体   English

作为参数传递的函数的异步执行

[英]Asynchronous execution of a function passed as an argument

I'm facing the following problem. 我正面临以下问题。 I want to use Google's geocoding service to draw some markers on the map. 我想使用Google的地理编码服务在地图上绘制一些标记。 However, the marker is instantiated before geocoding even finished it's job. 但是,标记是在进行地理编码甚至完成其工作之前实例化的。 drawMarker function will return a Marker with location undefined. drawMarker函数将返回location未定义的Marker

I tried passing the geocoding function as an argument to drawMarker function, and executing it there. 我尝试将地理编码功能作为参数传递给drawMarker函数,然后在此处执行。 I thought that this way I'd achieve synchronous behaviour, which is not the case. 我认为这样可以实现同步行为,事实并非如此。 Simplified code follows: 简化的代码如下:

drawMarker(i, map, codeAddress, locationsToConvert[i]);

function drawMarker(i, map, func, arg) {
    var location = func.apply(this, [arg]);
    return new google.maps.Marker({
        position: {lat: location.lat, lng: location.lng},
        map: map,
        html: locations[i][0],
        id: i
    });
}

function codeAddress(address) {
    geocoder.geocode( { 'address': address}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            return results[0].geometry.location
        }
    });
}

What are my solutions, which one's best, perhaps: 我最好的解决方案是什么:

  • using the Promise interface? 使用Promise界面?
  • doing everything in one function and instantiating Marker in the callback of the geocode service? 在一个功能中完成所有操作并在地址解析服务的回调中实例化Marker
  • other? 其他?

You could try getting the address first and calling drawMarker from the callback once you have it. 您可以尝试先获取地址,并在drawMarker回调后从回调中调用drawMarker Edited drawMarker to something close to how it would look, I do not have full code so might not be 100% correct. drawMarker编辑为接近外观,我没有完整的代码,因此可能不是100%正确。

codeAddress(locationsToConvert[i]);

function drawMarker(i, map, location) {
    return new google.maps.Marker({
        position: {lat: location.lat, lng: location.lng},
        map: map,
        html: locations[i][0],
        id: i
    });
}

function codeAddress(address) {
    geocoder.geocode( { 'address': address}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            drawMarker(i, map, results[0].geometry.location);
        }
    });
}

You have to put the drawMarker inside the geocoder callback 您必须将drawMarker放入地址解析器回调中

function codeAddress(address) {
    geocoder.geocode({ 'address': address}, function(results, status) {

        if (status == google.maps.GeocoderStatus.OK) {
            drawMarker(map,results[0].geometry.location);
        }
    });
}

take a look at this -> fiddle for the example 看看这个-> 小提琴的例子

Why not convert the location then call the draw function once it returns? 为什么不转换location然后在绘制函数返回后调用它呢?

Something similar to the below example (will change depending on the promise lib you are using) -- also can't promise there aren't any syntax errors in the example. 类似于以下示例(将根据您使用的Promise lib进行更改)-也不能保证示例中没有任何语法错误。

function geocodeAsync(addressToConvert) {
    return new Promise((resolve, reject) => {
      geocoder.geocode( {'address': addressToConvert }, (results, status) => {
        if (status == google.maps.GeocoderStatus.OK) {
            resolve(results[0].geometry.location);
        }
        else {
            reject(status);
        }
      });
    });
}
let loc = locationsToConvert[i];
var promise = geocodeAsync(loc)
promise.then(result => {
  let marker = new google.maps.Marker({
        position: {lat: result.lat, lng: result.lng},
        map: map,
        html: loc[0],
        id: i
    });
  // add marker to google maps
})
.catch(err => console.error(err));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM