Jimmy Genslinger Jimmy Genslinger - 4 months ago 11
Javascript Question

Using Deferred with AJAX

I have a series of js functions that are making database calls using ajax, and I need them to finish and update variables before moving to the final function. I'm trying to use jquery $.when and am having no luck...in the attached jsfiddle you can see that the final function result is being displayed before the two primary functions are being updated.

http://jsfiddle.net/b20hvyyp/

var x1 = '%';
var x2 = '%';

main();

function main(){
logProgress('start');
$.when(a(), b()).done(logProgress(x1 + x2));
}

// called by main()
function a() {
return $.ajax("/echo/html").pipe(function(data){
function changex1 () {
x1 = 'x1Changed';
};

setTimeout(changex1(),2000);
logProgress(x1);
});
}

// called by a()
function b() {
return $.ajax("/echo/html").pipe(function(data){
function changex2 () {
x2 = 'x2Changed';
};

setTimeout(changex2(),5000);
logProgress(x2);
});
}

function logProgress(message){
$('#progress').append('<li>'+message+'</li>');
}


Any help would be greatly appreciated!!

Answer

Two things should be noted here. The functions a() & b() returns deferred objects from the ajax call. These deferred objects will be resolved as soon as the ajax calls complete. So, there is no way for you to detect the execution of timeout callbacks. The next thing is, when() function takes a list of deferred object and returns a single deferred object which will be resolved once all the input deferred objects are resolved. So, the done function on the when() returned deferred should get a callback function instead of a statement like logProgress(x1 + x2). Here is the link with modifications that works: Link

var x1 = '%';
var x2 = '%';

main();

function main(){
    logProgress('start');
    console.log('asdf')
    $.when(a(), b()).done(function() {
    logProgress(x1 + x2)
    });
//  a().done(function(){
//    logProgress(x1 + x2);
//  });
}

// called by main()
function a() {
	logProgress('a called');
  return $.ajax("/echo/html").pipe(function(data){
    function changex1 () {
	  	x1 = 'x1Changed';
    };
    
    changex1();
    logProgress(x1);
  });
}

// called by a()
function b() {
	logProgress('b called')
  return $.ajax("/echo/html").pipe(function(data){
    function changex2 () {
	  	x2 = 'x2Changed';
    };
    
    changex2();
    logProgress(x2);
  });
}

function logProgress(message){
    $('#progress').append('<li>'+message+'</li>');
}
<ul id="progress">
</ul>

enter code here
Comments