jQuery jqXHR - cancel chained calls, trigger error chain

拜拜、爱过 提交于 2019-12-17 10:46:36

问题


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.

  1. The serverside method always returns a JSON object:

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

  2. The client-side utility initiates the ajax call like this

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

  3. 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.


回答1:


(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;
}


来源:https://stackoverflow.com/questions/5111695/jquery-jqxhr-cancel-chained-calls-trigger-error-chain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!