chain callback using deferred and pipe

2019-05-03 23:35发布

问题:

I am struggling to chain the callback with pipes using deferred. It seems to work just fine but in the callback2, it brings me data from callback1. Here is how the code looks like:

var getCall1 = function() {
    return $.ajax(url, {
        type: "GET",
        data: { },
        contentType: "application/json",
        dataType: "json"
    });
}


var getCall2 = function () {
    return $.ajax(url, {
        type: "GET",
        data: {},
        contentType: "application/json",
        dataType: "json"
    });
}

var callback1 = function (data)
            {
                alert('call 1 completed');
            };

var callback2 = function (data)
            {
                alert('call 2 completed');
            };

$.when(getCall1()).done(callBack1).pipe(getCall2()).done(callBack2);

What am i missing here?

--Edit--

If i break them in to two deferred calls, it works but then whats the use of chaining and pipe?

$.when(getCall1()).done(callBack1);
$.when(getCall2()).done(callBack2);

--Correct way to do this--

var getCall1 = function() {
    return $.ajax(url, {
        type: "GET",
        data: { },
        contentType: "application/json",
        dataType: "json"
    });
}.pipe(function (d){return d});


var getCall2 = function () {
    return $.ajax(url, {
        type: "GET",
        data: {},
        contentType: "application/json",
        dataType: "json"
    });
}.pipe(function (d){return d});

var callback1 = function (data)
            {
                alert('call 1 completed');
            };

var callback2 = function (data)
            {
                alert('call 2 completed');
            };

        $.when(getCall1, getCall2).done(function(d1, d2){
            callback1(d1);
            callback2(d2);

        });

回答1:

You should write pipe(getCall2), not pipe(getCall2()). deferred.pipe() expects a callback returning a deferred, not the deferred itself. Which makes sense, as the point is to chain requests (i.e. only start the second ajax call after the first has finished), and you only get the deferred after you started the action.



回答2:

What i understand in your code is you want to call getCall2 only if getCall1 successed.

So your code seems to be good. I tried it in jsFiddle (with a more simple example) and it works great for me :

http://jsfiddle.net/PG3aN/

Maybe it's a stupid question but are you sure that getCall1 and getCall2 should not simply return the same result from server ? That could explain why you get same data in callbacks 1 and 2.

Other question, in your last code sample, you write

var getCall1 = function() {
return $.ajax(url, {
        type: "GET",
        data: { },
        contentType: "application/json",
        dataType: "json"
    });
}.pipe(function (d){return d});

Does the last pipe change something on your code behaviour ?

And a last remark about your last code sample, the expected result is not the same. In this code you wrote that you will call callback1 and callback2 only if both getCall1 and getCall2 successed. Which is not the same behaviour as your first code.

Edit : a new jsFiddle with real asynchronous result

http://jsfiddle.net/PG3aN/1/