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

Asynchronous execution of a function passed as an argument

本文关键字:异步 执行 函数 参数传递      更新时间:2023-09-26

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

我尝试将地理编码函数作为参数传递给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
        }
    });
}

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

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

您可以尝试先获取地址,并在获得地址后从回调中调用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);
        }
    });
}

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

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

看看这个 -> 小提琴的例子

为什么不转换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));