我正在为jQuery AJAX方法创建一个包装器,因为我的AJAX请求在实际进行之前依赖于异步工作。
我目前正在做的是:http://pastie.org/private/bfdvep4kcdclzupsyddmiq
var ajax = function (options) {
var deferred = $.Deferred();
doAsyncWork()
.done(function (attributes) {
$.ajax(options)
.done(function () {
deferred.resolve.apply(this, arguments);
})
.fail(function () {
deferred.reject.apply(this, arguments);
});
})
.fail(function () {
deferred.reject();
});
return deferred.promise();
};
ajax().readyState // undefined
它有一个返回promise的外部延迟。我在实际执行AJAX请求之前解除了doAsyncWork()并等待它完成。现在,虽然这有效,但问题是当其他脚本使用包装器时,因为它们无法访问jQuery XHR对象的属性。
有没有办法优雅地解决这个问题?
答案 0 :(得分:2)
问题是:他们为什么要这样做?您是否尝试使用包装器透明地替换$.ajax()
?这将很快变得复杂,因为您必须考虑jqXHR
的所有属性和方法。
从理论上讲,这样的事情是可能的,但我不会称之为优雅,不推荐:
var ajax = function (options) {
var deferred = $.Deferred();
var promise = deferred.promise();
doAsyncWork()
.done(function (attributes) {
$.ajax(options)
.done(function () {
promise.readyState = 4
deferred.resolve.apply(this, arguments);
})
.fail(function () {
promise.readyState = 4
deferred.reject.apply(this, arguments);
});
})
.fail(function () {
deferred.reject();
});
promise.readyState = 0;
return promise;
};
其他的readystate设置应该转到适当的回调(JQuery中没有onreadystatechange
)。
那么,该怎么办?
如果其他脚本想要使用您的包装器,则必须使用Deferred API。如果由于某种原因他们确实需要访问jqXHR
对象,您可以像这样提供:
var ajax = function (options, xhrReadyCallback) {
var deferred = $.Deferred();
doAsyncWork()
.done(function (attributes) {
var xhr = $.ajax(options)
.done(function () {
deferred.resolve.apply(this, arguments);
})
.fail(function () {
deferred.reject.apply(this, arguments);
});
xhrReadyCallback(xhr);
})
.fail(function () {
deferred.reject();
});
return deferred.promise();
};
用法:
ajax(options, function(xhr) {
// now available:
xhr.readyState;
});
答案 1 :(得分:0)
没有办法直接传递jqXHR对象,因为它不是在函数返回时创建的。
但是 - 不要忘记done
和fail
回调中的jqXHR 分别可用作第三个和第一个参数。