JSFiddle - React, Tailwind, and code Playground

by Tomas Kirda

HTML

<b>Expected Result</b>
<br />a2 fail
<br />a2 always
<br />a3 done
<br />a3 always
<br />a1 done
<br />a1 always
<br />defer always
<br />----------
<br />
<br />
<b>Actual Result</b>
<br />

JavaScript

var a1 = $.Deferred();
var a2 = $.Deferred();
var a3 = $.Deferred();

a1.done(function () {
    $('body').append('a1 done<br />');
}).fail(function () {
    $('body').append('a1 fail<br />');
}).always(function () {
    $('body').append('a1 always<br />');
});

a2.done(function () {
    $('body').append('a2 done<br />');
}).fail(function () {
    $('body').append('a2 fail<br />');
}).always(function () {
    $('body').append('a2 always<br />');
});

a3.done(function () {
    $('body').append('a3 done<br />');
}).fail(function () {
    $('body').append('a3 fail<br />');
}).always(function () {
    $('body').append('a3 always<br />');
});

/*
$.when(a1).done(a2).done(a3).then(function() {
    $('body').append('defer always <-- should be after all<br />'); 
});
*/

whenAllResolved(a1, a2, a3).done(function () {
    $('body').append('defer always <-- should be after all<br />');
});

function whenAllResolved() {
    var d = $.Deferred(),
        args = arguments,
        verifyDeferreds = function () {
            var allResolved = true;
            $.each(args, function (i, arg) {
                if (arg.state() === 'pending') {
                    allResolved = false;
                    return false;
                }
            });
            if (allResolved) {
                d.resolve();
            }
        };

    $.each(arguments, function (i, arg) {
        arg.always(verifyDeferreds);
    });

    return d;
}

setTimeout(function () {
    a1.resolve();
}, 5000);
setTimeout(function () {
    a2.reject();
}, 1000);
setTimeout(function () {
    a3.resolve();
}, 3000);