JSFiddle - React, Tailwind, and code Playground

by jfriend00

HTML

<button onclick="test(false)">Go</button>
<button onclick="test(true)">Fail</button><br><br>
<div id="results"></div>

CSS

#results {
    font-family: "Courier New";
}

JavaScript

function log(args) {
    var str = "";
    for (var i = 0; i < arguments.length; i++) {
        if (typeof arguments[i] === "object") {
            str += JSON.stringify(arguments[i]);
        } else {
            str += arguments[i];
        }
    }
    var div = document.createElement("div");
    div.innerHTML = str;
    document.getElementById("results").appendChild(div);
}

function logClear() {
    document.getElementById("results").innerHTML = "";
}


jQuery.MultiDeferred = function(/* zero or more promises */) {

    // make the Deferred
    var self = jQuery.Deferred();
    // get the promise so new methods can be added to it too
    var promise = self.promise();

    var remainingToFinish = 0;
    var promises = [];
    var args = [];
    var anyFail = false;
    var failImmediate = false;
    
    function _add(p) {
        // save our index in a local variable so it's available in this closure later
        var index = promises.length;
        
        // save this promise
        promises.push(p);
        // push placeholder in the args array
        args.push([null]);

        // one more waiting to finish
        ++remainingToFinish;

        // see if all the promises are done
        function checkDone(fail) {
            return function() {
                anyFail |= fail;
                // make copy of arguments so we can save them
                args[index] = Array.prototype.slice.call(arguments, 0);
                --remainingToFinish;
                
                // send notification that one has finished
                self.notify.apply(self, args[index]);
                // if all promises are done, then resolve or reject
                if (self.state() === "pending" && (remainingToFinish === 0 || (fail && failImmediate))){
                    var method = anyFail ? "reject" : "resolve";
                    self[method].apply(self, args);
                }
            }
        }
        // add our own monitors so we can collect all...