承诺和经常性的AJAX调用

我试图想出一个函数,其签名与jQuery.ajax相同。 它是一个单独的函数,因为根据响应中的HTTP状态,它应该完成并解析返回的promise,或者发出具有相同参数的延迟后续AJAX请求(因此重现)。 虽然我有一个有效的解决方案,但我觉得它是一个承诺反模式,因为我明确地调用$.Deferred()来表示进程的状态。 问题:

  • 是否有可能重用$.ajax调用返回的“thenable”对象,就像链接后续调用返回的promise一样?
  • 每次调用另一个$.ajax时,你如何在promise链上加入progress调用?

请参考我的function:

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

是否可以重用$ .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(); }