iCollect.it Ltd
iCollect.it Ltd

Reputation: 93561

Simplest way to combine jQuery promises?

I have many situations where I need to accumulate multiple jQuery promises (animation or Ajax or "other"), but the simple test I tried did not wait for all of them to finish (or for any of them):

JSFiddle: http://jsfiddle.net/TrueBlueAussie/j7EL4/2/

function makePromises() {
    $('#box1').animate({
        left: 300
    }, 4000);
    $('#box2').animate({
        left: 300
    }, 1000);
    $('#box3').animate({
        left: 300
    }, 2000);
    $('#box4').animate({
        left: 300
    }, 3000);
    return $('.box').promise();
};

$.when.apply($, makePromises()).then(function(){
    $('.box').addClass("done");
});

Worst case, I would have expected it to wait for the first match before making all the boxes grey.

Why is this not working as expected?

Update:

Now that I know jQuery correctly combines promises for multiple elements, I note you can also use an empty jQuery object's promise to provide an empty promise

e.g.

return $().promise();

This is great as an early return value (e.g. when no animations are started at all).

Upvotes: 0

Views: 78

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074138

Why is this not working as expected?

Because apply accepts an array as its second argument, but you're passing it a Promise.

Since $(".box").promise() returns a promise that is resolved when all the queued actions are done, and isn't an array, you can't use it with apply like that.

All you need to do is use the result directly:

makePromises().then(/*...*/);

Updated Fiddle

(A. Wolff's code:

$.when(makePromises()).then(/*...*/);

...would also work, but is unnecessary indirection unless you have other promises you also need to combine this with.)

Upvotes: 2

Related Questions