rgandoin
rgandoin

Reputation: 39

jQuery: get the resolve from a $.Deferred contained in a function

If I have a $.Deferred with several chained promises in a function, and I call that function, how could I know when that Deferred is resolved ? For instance : http://jsfiddle.net/5AWK4/

jQuery(function($){
    var $div = $('<div>hello world</div>').appendTo('body');

    var test = (function(){
        var dfd = new $.Deferred();
        dfd.then(function(){
            return $div.animate({width:300}, 5000, 'swing', function(){return $div.append('<br>line 1');});
        })
        .then(function(){
            return $div.append('<br>line 2');
        });
        return dfd.resolve();
    });

    $.when(test()).then(function(){
        $div.append('<br>line 3');
    });

});

When I run that code, I have the following:

hello world
line 3
line 1
line 2

What I am expecting is having «line 3» display after my Deferred returned by my function has resolved. I tried to return only dfd in the function, and the call test().resolve() but it won't work either.

Thanks in advance

Upvotes: 0

Views: 256

Answers (1)

adeneo
adeneo

Reputation: 318182

First you create a Deferred object, then you return the promise of that Deffered object, and at a later time, say after some async method has completed you resolve that promise, like so:

jQuery(function($){
    var $div = $('div');

    var test = (function(){
        var dfd = new $.Deferred();
        $div.animate({width:300}, 5000, 'swing', function(){
            dfd.resolve(); //line 3 will printed now, i.e. before line 1
            $div.append('<br>line 1'); //line 1 will be printed after the promise has been resolved
        });
        return dfd.promise();
    });

    $.when(test()).then(function(){
        $div.append('<br>line 3');
    });
});

FIDDLE

Now, append() is a synchronous operation, so it needs no promise, and animate has it's own built in callback, so you can achieve the same by just doing:

jQuery(function($){
    var $div = $('div');

    var test = function(elem, callback){
        elem.animate({width:300}, 5000, 'swing', function(){
            callback();
        });
    };

    test($div, function() {
        $div.append('<br>line 1');
        $div.append('<br>line 2');
        $div.append('<br>line 3');
    });
});

FIDDLE

Upvotes: 1

Related Questions