Chaining ajax requests with jQuery's deferred

后端 未结 7 2362
天涯浪人
天涯浪人 2021-02-19 19:46

I have a web app which must call the server multiple times. So far, I had a long nested callback chain; but I would like to use jQuery\'s when,then etc

7条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-02-19 20:28

    The answer cdr gave, which has the highest vote at the moment, is not right.

    When you have functions a, b, c each returns a $.Deferred() object, and chains the functions like the following:

    a().then(b).then(c)
    

    Both b and c will run once the promise returned from a is resolved. Since both then() functions are tied to the promise of a, this works similiar to other Jquery chaining such as:

    $('#id').html("
    hello
    ").css({display:"block"})

    where both html() and css() function are called on the object returned from $('#id');

    So to make a, b, c run after the promise returned from the previous function is resolved, you need to do this:

    a().then(function(){
        b().then(c)
    });
    

    Here the call of function c is tied to the promise returned from function b.

    You can test this using the following code:

    function a() {
        var promise = $.Deferred();
        setTimeout(function() {
            promise.resolve();
            console.log("a");
        }, 1000);
        return promise;
    }
    
    function b() {
        console.log("running b");
        var promise = $.Deferred();
        setTimeout(function () {
            promise.resolve();
            console.log("b");
        }, 500);
        return promise;
    }
    
    function c() {
        console.log("running c");
        var promise = $.Deferred();
        setTimeout(function () {
            promise.resolve();
            console.log("c");
        }, 1500);
        return promise;
    }
    
    a().then(b).then(c);
    a().then(function(){
        b().then(c)
    });
    

    Change the promise in function b() from resolve() to reject() and you will see the difference.

提交回复
热议问题