cancel chained calls, trigger error chain

I am creating a ajax utility for interfacing with my server methods. I would like to leverage jQuery 1.5+ deferred methods from the object returned from the jQuery.ajax() call. The situation is following.

  • The serverside method always returns a JSON object:

    { success: true|false, data: ... }

  • The client-side utility initiates the ajax call like this

    var jqxhr = $.ajax({ ... });

  • And the problem area:

    jqxhr.success(function(data, textStatus, xhr) {
         if(!data || !data.success) { 
             ???? // abort processing, trigger error
         }
    });
    return jqxhr; // return to caller so he can attach his own handlers
    
  • So the question is how to cancel invocation of all the callers appended success callbacks an trigger his error handler in the place mentioned with ???? ?

    The documentation says the deferred function invocation lists are FIFO, so my success handler is definitely the first one.


    ( UPDATE: Please note that currently jQuery Promises are not compatible with the Promises/A+ specification - more info in this answer.)

    In your function where you create the AJAX request you can also create a deferred object and return a promise to the caller after binding its resolve and reject functions to the appropriate callbacks of the $.ajax request with some custom data verification, like this:

    function makerequest() {
    
        var deferred = $.Deferred();
        var promise = deferred.promise();
    
        var jqxhr = $.ajax({
            // ...
        });
    
        jqxhr.success(function(data, status, xhr) {
            if (!data || !data.success) {
                deferred.reject(jqxhr, 'error');
            } else {
                deferred.resolve(data, status, xhr);
            }
        });
    
        jqxhr.error(function(jqXHR, status, error) {
            deferred.reject(jqXHR, status, error);
        });
    
        return promise;
    }
    

    Now anyone will be able to use it like any promise like this to your function:

    var request = makerequest();
    
    request.done(successCallback);
    request.fail(errorCallback);
    

    Or even just:

    makerequest().then(successCallback, errorCallback);
    

    If you also add this:

        promise.success = promise.done;
        promise.error = promise.fail;
    

    then your caller will have (maybe more familiar) interface of .success() and .error() like with pure $.ajax() calls:

    var request = makerequest();
    
    request.success(successCallback);
    request.error(errorCallback);
    

    (The implementation of .complete() is left as an exercise for the reader.)

    See this demos:

  • http://jsfiddle.net/_rsp/r2YnM/
  • http://jsfiddle.net/_rsp/r2YnM/1/ (more verbose)
  • Here's another example pulled directly from a working project:

    function ajax(url, data) {
        var self = this;
        var deferred = $.Deferred();
        var promise = deferred.promise();
    
        var jqxhr = $.ajax({
            url: url,
            data: JSON.stringify(data),
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            type: 'POST'
        }).done(function (msg, status, xhr) {
            if (!msg || msg.Error) {
                self.doError(msg.Error);
                deferred.reject(jqxhr, 'error');
            } else {
                deferred.resolve(msg, status, xhr);
            }
        });
    
        return promise;
    }
    
    链接地址: http://www.djcxy.com/p/55344.html

    上一篇: 我是否应该避免异步处理Promise拒绝?

    下一篇: 取消链接调用,触发错误链