函数会在返回之前等待异步函数完成吗?

时间:2011-06-08 19:57:27

标签: javascript google-maps

假设我有这些地理编码调用:

function myFunction(marker1,marker2) {
  var firstAddress  = null;
  var secondAddress = null;
  geocoder.geocode({'latLng': marker1.getPosition()}, function(results, status) {
    # if geocoding successful, set firstAddress
  })

  geocoder.geocode({'latLng': marker2.getPosition()}, function(results, status) {
    # if geocoding successful, set secondAddress
  })
  return [firstAddress,secondAddress];

}

假设我打电话给myFunction。地理编码调用是异步的,对吧?所以它会快速执行并返回,在结果上调用回调。当我返回地址时,地理编码会完成吗?我如何确保在返回之前完成这两个功能?

3 个答案:

答案 0 :(得分:5)

简答:不。在AJAX完成之前,您几乎会立即到达myFunction的返回行,很可能是

最好的办法是强制geoCoder的请求同步。如果不能,那么您需要做的是设置一个全局标志,指示两个请求何时完成并等待设置该标志。如果是,那么您可以收集数据,构建数组并返回它。

function myFunction(marker1,marker2) {
  var firstAddress  = null;
  var secondAddress = null;

  document.geoCodeRequestCompleteFlag = 0;

  geocoder.geocode({'latLng': marker1.getPosition()}, function(results, status) {
    # if geocoding successful, set firstAddress
  })

  geocoder.geocode({'latLng': marker2.getPosition()}, function(results, status) {
    # if geocoding successful, set secondAddress
  })

  setTimeout( function( ) {
    document.geoCodeRequestCompleteFlag = -1;
  }, 15000 ); // -- ensure that we don't get stuck indefinitely

  while( document.geoCodeRequestCompleteFlag < 2 && document.geoCodeRequestCompleteFlag > 0 ) {
    // wait
  }

  if( document.geoCodeRequestCompleteFlag < 0 ) {
    return 'timeout';
  } else {
    return [firstAddress,secondAddress];
  }
}

请务必在document.geoCodeRequestCompleteFlag++marker1.getPosition()回调中添加marker2.getPosition()

缺点是,如果您的请求需要很长时间,浏览器可能会终止您的脚本。

答案 1 :(得分:1)

如果geocoder lib实际上是异步的,那么在获得实际数据之前将返回数组。

两种方式(我认为可以解决这个问题),使myFunction基于回调或强制地理编码器以某种方式同步

答案 2 :(得分:1)

不,它不会。你需要以某种方式协调两个请求的回调。处理它的一种简单方法是在每个回调中调用相同的函数,传入相关的地址。通过闭包维护一个数组来保存地址。当阵列达到所需大小时,您知道可以继续。类似的东西:

var allAddresses = [];

var coordinate = function(address) {
   allAddresses.push(address); // addAddresses is bound to this function via closure
   if (allAddresses.length === 2) { 
      // proceed
   }
}

然后,您可以在回调中调用coordinate谷歌API。

请注意,您需要处理错误情况,但使用上述模板应该非常简单....