我正在尝试提出一个签名与jQuery.ajax
相同的函数。它是一个单独的函数,因为根据响应中的HTTP状态,它应该完成并解析返回的promise,或者发出具有相同参数的延迟后续AJAX请求(因此重现)。虽然我有一个有效的解决方案,但我觉得它是一个承诺反模式,因为我明确地调用$.Deferred()
来表示进程的状态。问题:
$.ajax
调用返回的“可用”对象,如同后续调用返回的承诺一样?progress
时,您如何在承诺链上加入$.ajax
调用?请参阅我的功能:
callAPI = function(jqAjaxOptions, deferred) {
if (deferred == null) {
deferred = $.Deferred();
}
$.ajax(jqAjaxOptions).always(function(data, status, xhr) {
var args;
args = _.toArray(arguments);
switch (xhr.status) {
case 200:
return deferred.resolve.apply(deferred, args);
case 201:
case 202:
return setTimeout(function() {
return callAPI(jqAjaxOptions, deferred);
}, 2000);
default:
deferred.reject.apply(deferred, args);
if (data.responseText) {
return app.notifier.set(JSON.parse(data.responseText));
} else {
return app.notifier.set({
title: "Couldn't contact data server.",
content: "It seems the API server is down. Please contact the DAV team."
});
}
}
});
return deferred.promise();
};
答案 0 :(得分:1)
是否可以重用$ .ajax调用返回的“thenable”对象,就像链接后续调用返回的promise一样?
是和否。您将丢失多个参数,并且无法发出进度事件。它看起来像这样:
function timeout(ms) {
var d = $.Deferred();
setTimeout(d.resolve, ms);
return d.promise();
}
function callApi(ajaxOptions) {
function tryit () {
return $.ajax(ajaxOptions).then(data) {
if (this.status == 200)
return data;
else if (this.status == 201 || this.status == 202)
return timeout(2000).then(tryit);
else
return $.Deferred().reject(this.responseText
? JSON.parse(this.responseText)
: {
title: "Couldn't contact data server.",
content: "It seems the API server is down. Please contact the DAV team."
});
});
}
return tryit();
}
每次调用另一个$ .ajax时,你如何在promise链上加入进度调用?
只需致电notify
:
function callApi(ajaxOptions) {
var deferred = $.Deferred();
function tryit() {
$.ajax(jqAjaxOptions).always(function() {
switch (this.status) {
case 200:
return deferred.resolveWith(this, arguments);
case 201:
case 202:
deferred.notify("Next try in 2s");
return setTimeout(tryit, 2000);
default:
deferred.notify(this.responseText
? JSON.parse(this.responseText);
: {
title: "Couldn't contact data server.",
content: "It seems the API server is down. Please contact the DAV team."
});
deferred.rejectWith(this, arguments);
}
});
}
tryit();
return deferred.promise();
}