Jake Wilson
Jake Wilson

Reputation: 91183

Wait for AJAX to complete before returning from function?

I have the following

function doAjax()
{
  var result = false;
  $.ajax(url, data)
    .done(function(){
       // Do a bunch
       // of computation
       // blah blah blah
       result = true;
    }).fail(function(){
       result = false;
    });
  return result;
}

function doSomething()
{
  if ( doAjax() == true )
    console.log('success');
  else
    console.log('failed');
}

function doSomethingElse()
{
  if ( doAjax() == true )
    console.log('success');
  else
    console.log('failed');
}

I have a function that runs some ajax, then returns true or false, depending on whether the ajax was successful or not. This ajax function I call from multiple places in my code.

Because the function ends before the ajax finishes, it always returns false. How do I avoid this?

I have read something suggesting that I do a return $.ajax() in my function and then move the .done() and .fail() functions to my doSomething() and doSomethingElse() functions. However, in my .done() method, I do a BUNCH of computation. Lots of code. So the problem is, that if I move the .done() function to my other functions, I am duplicating a bunch of code.

How do I avoid this? Just wrap the computation into it's own function and call it wherever necessary?

Upvotes: 11

Views: 25291

Answers (4)

Soren
Soren

Reputation: 14688

Restructure your code to use callbacks instead of returns, like this...

function doAjax(callback)
{
  $.ajax(url, data)
    .done(function(){
       // Do a bunch
       // of computation
       // blah blah blah
       callback(true);
    }).fail(function(){
       callback(false);
    });
}

function doSomething()
{
  doAjax(function(result){
    if (result == true )
       console.log('success');
    else
       console.log('failed');
  });
}

function doSomethingElse()
{
  doAjax(function(result){
    if (result == true )
       console.log('success');
    else
       console.log('failed');
  });
}

Upvotes: 12

Amir Popovich
Amir Popovich

Reputation: 29836

Techincally you can make you ajax synchronous like this:

 $.ajax({url:myUrl, data:myData, async: false})

But this isn't recomended(only for really really specific things).
Otherwise, simply use callbacks as you can see in this example:

var menuId = $( "ul.nav" ).first().attr( "id" );    
var request = $.ajax({   
  url: "script.php",    
  type: "POST",    
  data: { id : menuId },   
  dataType: "html"    
});

request.done(function( msg ) {    
  $( "#log" ).html( msg );   
});

request.fail(function( jqXHR, textStatus ) {    
  alert( "Request failed: " + textStatus );    
});

Read more here.

Upvotes: 3

BlitZ
BlitZ

Reputation: 12168

It will not work, while your Ajax is in asynchronous mode (async: false). Try to structurize your code this way:

function doABuncnchOfComputation(args){ // no duplicates here
    // Do a bunch
    // of computation
    // blah blah blah
}

// doSomething:
$.ajax(url, data)
    .done(function(){
       doABuncnchOfComputation(...); // call with proper arguments, possibly received from server
       console.log('doSomething succeeded');
    }).fail(function(){
       console.log('doSomething failed');
    });

// doSomethingElse:
$.ajax(url, data)
    .done(function(){
       doABuncnchOfComputation(...); // call with proper arguments, possibly received from server
       console.log('doSomethingElse succeeded');
    }).fail(function(){
       console.log('doSomethingElse failed');
    });

So your main computation block doABuncnchOfComputation() will remain intact and accesible for each async operation.

Setting Ajax mode to synchronous will hold browser from any execution, while network transmission is in active state. Due to possible network instability, it may lead to "bad" user experience - browser may hang, page will be inactive and unresponsive, while Ajax will send/receive or be waiting for data. It is highly unreliable and discouraging.

Upvotes: 1

Justinas
Justinas

Reputation: 43441

NEVER do return together with Ajax, it will never work. Use Ajax success function:

$.ajax({
   url: 'http://localhost',
   success: function(data){
        var doStuff = true;
        var responseFromServer = data;
        callSomeFooFunction();
        //return will not work!
   }
})

Upvotes: 1

Related Questions