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

时间:2016-04-20 19:30:21

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

我面临以下问题。我想使用Google的地理编码服务在地图上绘制一些标记。但是,在地理编码甚至完成它的工作之前,标记就会被实例化。 drawMarker函数将返回Marker location未定义。

我尝试将地理编码功能作为参数传递给drawMarker函数,然后在那里执行。我认为这样就可以实现同步行为,但情况并非如此。简化代码如下:

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
        }
    });
}

我的解决方案是什么,也许是最好的解决方案:

  • 使用Promise界面?
  • 在一个函数中执行所有操作并在地理编码服务的回调中实例化Marker
  • 其他?

3 个答案:

答案 0 :(得分:1)

您可以先尝试获取地址,然后在收到回拨后拨打drawMarker。编辑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);
        }
    });
}

答案 1 :(得分:1)

您必须将drawMarker放入地理编码器回调

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

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

看看这个 - > fiddle示例

答案 2 :(得分:0)

为什么不转换location然后在返回后调用draw函数?

类似于以下示例的内容(将根据您使用的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));