Wait for Ajax return in synchronous function

12

I have an operation that I need to perform synchronously, but some of the information I need can only be obtained via Ajax.

I tried to make everything synchronous with a wait for the Ajax return. The problem is that while any function is running, Ajax events that handle the successful return are not executed.

Here's an example of what I'm doing:

function foo () {
    var a = false;
    $.ajax({
        url: "foo" // substitua por qualquer URL real
    }).done(function () {
        a = true;
    });

    while(!a) { } // Isto é apenas para se ter uma espera.
    alert(a); // Isso nunca vai executar
}
foo();

And this has generated me a race condition : The function associated with the done event will not run while while is iterating, and while will never end until the done event does not run. / p>

Is there any way to reach my goal?

    
asked by anonymous 18.02.2014 / 21:01

3 answers

12

Yes, but first of all I need to make it clear that using ajax synchronously is highly contraindicated . The user interface will freeze until the ajax returns.

The code for this in jQuery is:

var a;
$.ajax({
    url: "foo", // substitua por qualquer URL real
    async: false
}).done(function () {
    a = true;
});
console.log(a);

while does not work because it is blocking the only thread used in JS. While the code does not exit while , the event loop does not progress, and the asynchronous events (the done / complete of the ajax included) are never processed. And so the value of a never changes, and while never ends, it's an infinite loop.

    
18.02.2014 / 21:05
2

Have you tried using callbacks?

function foo (callback) {
  $.ajax({
      url: "/minha_api",
      myCallback: callback,
      success: function(){
        this.myCallback(true);
      }          
  });     
}

foo(function(a){
   alert(a);
});
    
18.02.2014 / 22:29
1

In the latter case, when nothing is working:

function foo () {
    var a = false;
    $.ajax({
        url: "foo" // substitua por qualquer URL real
    }).done(function () {
        a = true;
    });

    setInterval(function () {
        if (a) {
            alert(a); // Isso pode acontecer
        }
    }, 100);
}

foo();
    
18.02.2014 / 21:20