2011-02-24 52 views
14

我正在创建一个与我的服务器方法接口的ajax实用程序。我想利用从jQuery.ajax()调用返回的对象中的jQuery 1.5+延迟方法。情况如下。jQuery jqXHR - 取消链接调用,触发错误链

  1. 的服务器端方法总是返回一个JSON对象:

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

  2. 的客户端程序发起Ajax调用这样

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

  3. 而且问题面积:

    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 
    

所以,问题是如何取消所有的来电者的调用附加成功回调与????提到的地方一个触发了自己的错误处理程序?

该文档说延迟函数调用列表是FIFO,所以我的成功处理程序绝对是第一个。

回答

29

更新: 请注意,目前jQuery的承诺不与Promises/A+ specification兼容 - 在this answer更多信息)

在你的功能,你创建的AJAX请求,你还可以创建一个延迟对象,返回承诺主叫绑定决心后,拒绝功能,一些自定义的数据验证$就请求相应的回调,像这样:

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

现在任何人都将是能够使用它像任何承诺,这样你的函数:

var request = makerequest(); 

request.done(successCallback); 
request.fail(errorCallback); 

甚至只是:

makerequest().then(successCallback, errorCallback); 

如果您还补充一点:

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

那么你的呼叫方(也许更熟悉).success()和.error()的接口像纯$ .ajax()调用一样:

var request = makerequest(); 

request.success(successCallback); 
request.error(errorCallback); 

(.complete()的实现仅供读者参考。)

看到这个演示:

再举一例直接从一个工作项目拉动:

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; 
} 
+4

**请注意**:这个答案的日期是2月11日,当时jQuery的版本是v1.5。随后对jQuery的改进使这个答案变得多余。从v1.6开始,普遍接受的解决方案将涉及'deferred.pipe()'和v1.8'deferred.then()',此时我们会写一些类似'function makerequest(){return jqxhr.then (function(data){return(data && data.success)?jqxhr:$ .Deferred()。reject(new Error('AJAX data error'))。promise();}); }'。 – 2014-06-17 04:54:32

+0

一旦我们开始返回一些不等于'jqXHR'的东西(如上面的答案中的'$ .Deferred()。promise'),我们就无法访问原始'jqXHR'对象的'.abort()'函数,并且可以如果需要,在请求解决之前不会中止请求。 – 2016-03-15 11:54:11