Chain ajax and execute it in sequence. Jquery Deferred

后端 未结 5 626
旧时难觅i
旧时难觅i 2020-11-30 02:53

I have 3 processes that needs ajax to complete. But it is asynchronous and it fails to do what I wanted to do..

Lets say:

function a(param1, param2)         


        
5条回答
  •  醉梦人生
    2020-11-30 03:21

    I see that c doesn't depend of b result, and b doesn't depend of a result.

    Following the GRASP principles (http://en.wikipedia.org/wiki/GRASP_(object-oriented_design), a mustn't know b and b mustn't know c.

    When we program, to remember the GRASP principles or guidelines is very important.

    High Cohesion and Low Coupling mean that our code will be better, more reusable and easier to maintain.

    The main function which knows a, b, and c must build the chained calls.

    The functions would be:

        function a(param1, param2) {
    
            var deferred = $.Deferred();
    
            console.log("    function a: begin. Params " + param1 + " and " + param2);
    
            mockPost("a_url").done(function() {
                console.log("    function a: end ok. Params " + param1 + " and " + param2);
                deferred.resolve();
            }).fail(function() {
                console.log("    function a: end fail. Params " + param1 + " and " + param2);
                deferred.reject();
            });
    
            return deferred.promise();
        }
    
        function b() {
    
            var deferred = $.Deferred();
    
            console.log("    function b: begin");
    
            mockPost("b_url").done(function() {
                console.log("    function b: end ok.");
                deferred.resolve();
            }).fail(function() {
                console.log("    function b: end fail.");
                deferred.reject();
            });
    
            return deferred.promise();
        }
    
        function c() {
    
            // We suppose that c function calls to post function and anything more
            return mockPost("c_url");
        }
    

    The main function would be:

        // Array with params for a function (a function is the first link in chain)
        var data = [{param1 : 1235, param2: 3214},  {param1 : 5432, param2: 9876}];
    
        // Array with calls to each fixed sequence a, b, and c. We iterate over data array
        var arrayFunctions = [];
        $.each(data, function(i,obj) {
            arrayFunctions.push(
                function() {
                    console.log("Params in data with index " + i + ":");
    
                    // We define the fixed sequence: a with params, b without params and c without params 
                    return $.iterativeWhen( 
                        function() {
                            return a(obj.param1, obj.param2);
                        },
                        b,
                        c
                    );
                }
            )
        });
    
        // Start the global process
        $.iterativeWhen.apply($, arrayFunctions)
        .done(function() {
            console.log ("----------------");
            console.log ("> Global Success");       
        })
        .fail(function() {
            console.log ("--------------");
            console.log ("> Global Fail");
        });
    

    $.iterativeWhen doesn't exist in jQuery, so I have built it. It works with jQuery 1.8 and later versions.

    $.iterativeWhen = function () {
    
        var deferred = $.Deferred();
        var promise = deferred.promise();
    
        $.each(arguments, function(i, obj) {
    
            promise = promise.then(function() {
                return obj();
            });
        });
    
        deferred.resolve();
    
        return promise;
    };
    

    The mockPost function simulates a call to $.post with a success probability:

    function mockPost(url) {
    
            var deferred = $.Deferred();
    
            setTimeout(function() {
                if (Math.random() <= 0.9) {
                    console.log("        request url: " + url +  "... ok");
                    deferred.resolve();
                } else {
                    console.log("        request url: " + url +  "... fail");
                    deferred.reject();
                }
            }, 1000);
    
            return deferred.promise();
        }
    

    The log output is:

    Params in data with index 0: 
        function a: begin. Params 1235 and 3214 
            request url: a_url... ok 
        function a: end ok. Params 1235 and 3214 
        function b: begin 
            request url: b_url... ok 
        function b: end ok. 
            request url: c_url... ok 
    Params in data with index 1: 
        function a: begin. Params 5432 and 9876
            request url: a_url... ok
        function a: end ok. Params 5432 and 9876 
        function b: begin 
            request url: b_url... ok 
        function b: end ok. 
            request url: c_url... ok 
    ---------------- 
    > Global Success 
    

    jsFiddle here: http://jsfiddle.net/E2tp3/

提交回复
热议问题