(更新: 请注意,目前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;
}
**请注意**:这个答案的日期是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
一旦我们开始返回一些不等于'jqXHR'的东西(如上面的答案中的'$ .Deferred()。promise'),我们就无法访问原始'jqXHR'对象的'.abort()'函数,并且可以如果需要,在请求解决之前不会中止请求。 – 2016-03-15 11:54:11