$.Defferred() done, fail, always

by protasovams

HTML

<button id="go">Start</button>
<hr />
<ol id="log"></ol>

CSS

li.ok {
    color: green;
}
li.error {
    color: red;
}
li.result {
    font-weight: bold;
}

JavaScript

$(function () {
    // helper to log messages to the screen
    function log(message, cssClass) {
        $("<li>", {text: message, "class": cssClass || "" }).appendTo("#log");
    }
    
    // helper that wraps an Ajax request and accepts/rejects it based on its content
    function checkedRequest(jqXHR, check) {
        var result = $.Deferred();

        // the Ajax request might return with 200 OK, 
        // even though the result actually indicates an error, so...
        jqXHR.done(function (data, textStatus, jqXHR) {
            if (check(data)) {
                log("response #" + data.id + " is valid", "ok");
                // ...if the check is OK then accept the result
                result.resolve(data, textStatus, jqXHR);
            } else {
                log("response #" + data.id + " is invalid", "error");
                // else reject the result with an error
                result.reject(jqXHR, textStatus, "data indicates an error");
            }
        }).fail(result.reject);
        
        return result.promise();
    }
    
    // example function that checks returned data for validity
    function myRequestChecker(data) {
        return !data.isError;
    }

    $("#go").click(function () {
        $("#log").empty();
        
        // a few example requests and their outcome for demonstrational purposes
        var requestDefinitions = [
                {data: {id: 1, isError: false}, delay: 0}, 
                {data: {id: 2, isError: false}, delay: 2}, 
                {data: {id: 3, isError: false}, delay: 1}, 
                {data: {id: 4, isError: true}, delay: 0}
            ],
            // now start a bunch of of parallel Ajax reqests...
            parallelRequests = $.map(requestDefinitions, function (req) {
                log("request #" + req.data.id + " starts");
            
                var jqXHR = $.post("/echo/json/", {
                    json: JSON.stringify(req.data), 
                    delay:...