admin管理员组

文章数量:1410674

Let's say I have these geocoding calls:

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];

}

Let's say I call myFunction. The geocode call is asynchronous, right? So it will execute and return quickly, calling the callback on results. Will the geocoding have finished when I return the addresses? How could I ensure that both functions finished before returning?

Let's say I have these geocoding calls:

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];

}

Let's say I call myFunction. The geocode call is asynchronous, right? So it will execute and return quickly, calling the callback on results. Will the geocoding have finished when I return the addresses? How could I ensure that both functions finished before returning?

Share Improve this question asked Jun 8, 2011 at 19:57 GeoGeo 97.1k120 gold badges352 silver badges534 bronze badges 3
  • That's what's meant by "asynchronous" - it happens outside the control flow of the original function call. – Pointy Commented Jun 8, 2011 at 20:13
  • Yeah. Thanks for clearing it up </ironic> – Geo Commented Jun 8, 2011 at 20:17
  • OK well the answer to your question is "no", and you can go figure out why. – Pointy Commented Jun 8, 2011 at 20:22
Add a ment  | 

3 Answers 3

Reset to default 5

Short answer: no. You will almost immediately get to the return line of myFunction, most likely well before the AJAX has pleted.

Your best bet is to force geoCoder's requests to be synchronous. If you can't, then what you will need to do is set a global flag indicating when both requests have pleted and wait for that flag to be set. If it is, then you can gather your data, construct your array, and return it.

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

Be sure to add a document.geoCodeRequestCompleteFlag++ inside your marker1.getPosition() and marker2.getPosition() callbacks.

The downside to this, is that if your requests take a long time, the browser may kill your script.

If the geocoder lib is actually asynchronous the array would be returned before you have the actual data yes.

Two ways (that i see to solve this), make myFunction callback-based or force geocoder to be synchronous somehow

no it wont. you need to coordinate the callbacks of the two requests somehow. One easy way to handle it is to call the same function in each callback, passing in the relevant address. Maintain an array via a closure to keep the addresses. When the array reaches the desired size, you know you can proceed. Something like:

var allAddresses = [];

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

you can then call coordinate in your callback to the google API.

Note that you will need to handle error conditions, but with the above template that should be pretty easy....

本文标签: javascriptWill the function wait for the asynchronous functions completion before returningStack Overflow