MgSam
MgSam

Reputation: 12813

JQuery Chaining Deferreds without callback pyramids

Is there a way to chain JQuery Deferreds to execute one after another without callback pyramids?

Right now I have to do something like this:

$.Deferred(function(dfd) {
    setTimeout(function() { 
        console.log('Foo'); 
        dfd.resolve(); 
    }, 1000);
})
.done(function() {
    $.Deferred(function(dfd) { 
        console.log('Bar');
        dfd.resolve();
    }).done(function() { 
         console.log('done');
    });
});

Output: Foo, Bar, done

I want to be able to do something like this:

$.Deferred(function(dfd) {
    setTimeout(function() { 
        console.log('Foo'); 
        dfd.resolve(); 
    }, 1000);
})
.then($.Deferred(function(dfd) { 
    console.log('Bar');
    dfd.resolve();
}))
.done(function() { console.log('done') });

Undesired Output: Bar, Foo, done

Thanks.

Upvotes: 3

Views: 401

Answers (2)

jcoffland
jcoffland

Reputation: 5428

I think you want to use $.when().

Something like this should work:

var d1 = $.Deferred(function(dfd) {
    setTimeout(function() { 
        console.log('Foo'); 
        dfd.resolve(); 
    }, 1000);
});

var d2 = $.Deferred(function(dfd) { 
    setTimeout(function() { 
      console.log('Bar');
      dfd.resolve();
    }, 2000);
});

$.when(d1, d2).then(function() {console.log('done')});

Upvotes: 0

Brad M
Brad M

Reputation: 7898

The issue with your code is you are passing .then() a jQuery object whereas it expects a function. This code executes foo-bar-done as required.

$.Deferred(function(dfd) {
    setTimeout(function() { 
        console.log('Foo'); 
        dfd.resolve(); 
    }, 1000);
}).then(function(){ 
    return $.Deferred(function(dfd) { 
         console.log('Bar');
         dfd.resolve();
     });
}).done(function() { console.log('done') });

Upvotes: 1

Related Questions