Can I manually resolve a deferred object if a call

2019-08-14 14:40发布

I'm trying to use a custom deferred object to manage some callbacks. I've figured out the easy case:

var deferred = $.Deferred();

deferred.done(function() {
    console.log( 'done' );
});

var json = $.getJSON('/foo');

json.then(
    function() {
        deferred.resolveWith(this, arguments);
    }  
);

But I need to inspect the response before resolving/rejecting. I'd like to add something like this:

deferred.pipe(
    function(response) {
        if (response.message === 'error') {
            return $.Deferred.reject(response);
        }
        return response;
    }
);

But when I do, my original done() callback is always called regardless. I'm pretty sure it's because once I call deferred.resolveWith() it's too late to "roll back" and mark it as rejected later. I know I could just move the conditional up into the first argument to json.then(), but that seems to miss the point of a deferred object -- I thought they were meant for encapsulating all of these behaviors into a single place.

Is it possible to put both the conditional and the callback into deferred while still resolving it elsewhere?

1条回答
乱世女痞
2楼-- · 2019-08-14 15:05

It seems like you goal is really just to separate out the functionality into two steps: validate the result of the ajax request, then handle the result. To do that, have an outer deferred that then gets replaced with an inner deferred that resolves or rejects based on the parameters returned by the ajax request.

var deferred = $.Deferred();

deferred.then(function(data){
    // new deferred that we will be returning
    var deferred = $.Deferred();
    if (data.success == true) {
        deferred.resolveWith(data.result);
    }
    else {
        deferred.rejectWith(data.error);
    }
    // any following chained methods will affect this returned deferred object
    return deferred;
}).then(
    // done callback
    function(result){
        console.log("Resolved!");
        console.dir(result);
    },
    // fail callback
    function(error){
        console.log("Rejected!");
        console.dir(error)
    }
);

var json = $.getJSON("/foo");
json.done(deferred.resolveWith);
查看更多
登录 后发表回答