3

lets say i have this async functuin:

function fooAsync(){
  callSomeApi(some_args, callbackFunction(results){
    return results; //i want to return the results here after the api call.
  }
}

i'm looking for a way to assign the return value from the prev function to a var and continue with the code only when i have this value.

//some code here
var foo = fooAsync();
//some code here after getting back from the async function.

the problem is that foo will be undefined since javascript will return before the inner async api call will finish. I know i can use callbacks for that but i'm looking for a way to 'lock' the async function and resume back only when it got the result. That way i wont have to pass all the code after the async call as a callback.

to make things short - how can i return value from async ajax call (in my case i call google maps api) in a regular sync way?

Sagiv Ofek
  • 25,190
  • 8
  • 60
  • 55
  • Not sure about JS, but in languages like C you can block on a condition variable until async function is done... –  Jul 20 '12 at 19:25
  • i'm interested on a way to do that on js.. – Sagiv Ofek Jul 20 '12 at 19:27
  • How exactly are you calling the api, show some code ? The easy solution would be to just do the call synchronously to begin with. – adeneo Jul 20 '12 at 19:31
  • @adeneo - i want to make this a general issue so the specific api is irrelevant to the question – Sagiv Ofek Jul 20 '12 at 19:32
  • You can't do that kind of blocking in javascript. You can turn the request into a synchronous request, however it is a very bad idea because it will result in a bad UX when the response doesn't happen in a timely fashion. The better way to handle it is to re-organize your code to work in an asynchronous way. – Kevin B Jul 20 '12 at 19:33
  • @sagivo - well, this is'nt really a general issue. Either you do the call synchronously or asynchronously, and you adapt your code to whatever floats your boat. There's no way to make the rest of your code wait for an async call without blocking, and making it wait with blocking is just the same as a synchronous call, so you might aswell just do that, allthough async is usually the preferred way to avoid blocking. – adeneo Jul 20 '12 at 19:37

1 Answers1

4

Generally it's a bad idea to make an ajax call synchronous. There is a property on the XMLHttpRequest object that you can set (jQuery allows you to do this easily) to make a synchronous ajax request. I'm not sure if the google maps API exposes this capability but you should check there first.

I know you said you don't want to work with callbacks but aside from doing something like this:

while(foo === undefined){
  sleep(5) //pseudo code sleep method
}

there really isn't any way to lock down the current execution context.

Also with the code you provided, that method would never return anything other than undefined. You are calling the api method (which executes asynchronously) and immediately returning control. The 'return' statement inside of the response handler of the api method call would only return inside of the anonymous function. So even if you were able to lock the thread until the results are back, you wouldn't have them.

If, however, you are interested in going about this in the correct manner then you should use the deferred / promise model that jQuery provides.

function fooAsync(){
  var deferred = $.Deferred();
  callSomeApi(some_args, callbackFunction(results){
    deferred.resolve(results) //i want to return the results here after the api call.
  }
  return deferred.promise();
}

Then you would change your calling code to be like this:

//some code here
$.when(fooAsync()).then(function(results){
    //use the results
});
//some code here after getting back from the async function.

jQuery Deferred Object Documentation

awbergs
  • 942
  • 4
  • 15