13

I need to write a function in JavaScript, which returns a state from calling an asynchronous function. However, the caller only receives the value and no callback function is to be provided. I tried something like:

function getState() {
    var ret = null;
    asyncCall("request",
        function() { ret = "foo"; } // callback
    );
    while (ret === null)
        ; // block on the asynchronous call
    return ret;
}

However, the loop is never going to end…

Any ideas? Thank you.

Tomalak
  • 332,285
  • 67
  • 532
  • 628
Ryan Li
  • 9,020
  • 7
  • 33
  • 62
  • 2
    Why do you want to block the asynchronous call in the first place? Doing this makes no sense. – Tomalak Dec 03 '10 at 13:30
  • 4
    @Tomolak: because it's a call provided by Firefox and I cannot change it. It's expected to take at most milliseconds, I don't want to refactor all my other code just because of this. – Ryan Li Dec 03 '10 at 13:32
  • Can you post the function that calls `getState()`? – Tomalak Dec 03 '10 at 13:39
  • @Tomolak: It's too long to be posted here and it's expected to be called from many places. Therefore, I expect this function to return a value. – Ryan Li Dec 03 '10 at 13:57
  • Did you get any working answer for this? I am also facing the same Issue and couldn't find any proper answer till now. Only option I had now is to refactor the code in many places to work with async method. – keya Sep 07 '17 at 19:31

5 Answers5

9

I think you're looking for StratifiedJS, http://stratifiedjs.org It allows you to "orchestrate" your async code exactly like you wrote, BEWARE that it "writes" like synchronous code, it will NOT block the rest of your application. You can use it anywhere by loading the apollo js library.

This is how it would look like in Stratified JavaScript:

function getState() {
  waitfor (var ret) {
    // block on the asynchronous call
    asyncCall("request", resume);
  }
  return ret;
}

of course there are modules/libraries that would just make it look like this: http://onilabs.com/modules#http

function getState() {
  return http.get("request");
}
tomg
  • 355
  • 2
  • 5
1

Unless I misunderstood your question, you could look at jQuery's ajaxStop() event - http://api.jquery.com/ajaxstop. This blocks until all ajax calls have completed. This obviously requires that all of your async calls be done thru jQuery.

$(document).ajaxStop(function() {
    // do your "ajax dependent" stuff here
});
Dave Black
  • 7,305
  • 2
  • 52
  • 41
1

Why not just:

asyncCall("request", function() {
    // here you can inspect the state
});

What's the point of the wrapper function?

Asynchronous functions work this way. If you want to block the execution, then use a synchronous call:

var state = syncCall("request");
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • It's something like a library since I am working across several platforms. And the rest of the code needs to wait for this special piece of information. No synchronous substitution is provided. – Ryan Li Dec 03 '10 at 13:36
  • 2
    @Šime: So you mean asynchronous calls could infect all other code calling it? I just want to know if there is a way to block on these async calls. – Ryan Li Dec 03 '10 at 13:40
  • 1
    @ryanli: There is no way to block async call unless you A: rewrite the async call to be synchronous or B: rewrite your code to work in an asynchronous environment. In javascript it is considered best practice to do B since 1999. – slebetman Dec 03 '10 at 13:50
1

The best would be to put the logic you want to have called into the callback function. Is there any reason why you can't do that?

You could use setInterval to check on the result, but that requires a callback function, too...

RoToRa
  • 37,635
  • 12
  • 69
  • 105
  • I am writing an extension, not normal document JavaScript. The rest part of the function relies on this state, and the only thing provided is an asynchronous function. – Ryan Li Dec 03 '10 at 13:34
0

what you are trying to do is a synchronous call, so its not a good idea to do it with a function designed for asynchronous call.

You have an answer here : How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

Community
  • 1
  • 1
Jean-Bernard Jansen
  • 7,544
  • 2
  • 20
  • 17