Jquery Ajax防止延迟顺序循环失败

所以,我将序列ajax链接在一起,按顺序加载一个url数组。 最初我使用.always() .then()而不是.always() ,并且无论哪种方式都可以正常工作 – 前提是所有url都存在。 但是,由于存在丢失文件的可能性,我想补偿这一点,然后最后通知用户哪些文件丢失,以便更容易纠正。

但是,问题是,在丢失的文件/ 404上,代码执行,就像它应该的那样,但随后退出循环,阻止任何进一步的ajax调用。 所以我认为,我需要一些方法来处理fail()并强制成功,或者某种其他方式覆盖404上的默认行为,因此它继续循环。

不幸的是,最接近谷歌的结果是如何做相反的事情(迫使成功失败)。

 var missing=[]; uLoadList.reduce(function(prev, cur, index) { return prev.then(function(data) { return $.ajax("/wiki/"+cur).always(function(data) { var temp = $('#mw-content-text',data); temp = $('pre',temp); if(temp.length > 0) { //handle success }else{ //handle failure missing.push(cur); } }); }); }, $().promise()).done(function() { if(missing.length > 0) { //notify of missing objects } //continue on. }); 

最后要注意的是,为了减轻混淆:URL和脚本本身位于MediaWiki网站上 – 所以即使返回404,也总会有页面内容,并且将包含id为“mw-content”的元素-文本”。

尝试

 (function ($) { $.when.all = whenAll; function whenAll(arr) { "use strict"; var deferred = new $.Deferred(), args = !! arr ? $.isArray(arr) ? arr : Array.prototype.slice.call(arguments) .map(function (p) { return p.hasOwnProperty("promise") ? p : new $.Deferred() .resolve(p, null, deferred.promise()) }) : [deferred.resolve(deferred.promise())], promises = { "success": [], "error": [] }, doneCallback = function (res) { promises[this.state() === "resolved" || res.textStatus === "success" ? "success" : "error"].push(res); return (promises.success.length + promises.error.length) === args.length ? deferred.resolve(promises) : res }, failCallback = function (res) { // do `error` notification , processing stuff // console.log(res.textStatus); promises[this.state() === "rejected" || res.textStatus === "error" ? "error" : "success"].push(res); return (promises.success.length + promises.error.length) === args.length ? deferred.resolve(promises) : res }; $.map(args, function (promise, index) { return $.when(promise).always(function (data, textStatus, jqxhr) { return (textStatus === "success") ? doneCallback.call(jqxhr, { data: data, textStatus: textStatus ? textStatus : jqxhr.state() === "resolved" ? "success" : "error", jqxhr: jqxhr }) : failCallback.call(data, { data: data, textStatus: textStatus, jqxhr: jqxhr }) }) }); return deferred.promise() }; }(jQuery)); // returns `Object { // success: Array[/* success responses*/], // error: Array[/* error responses */] // }` 

 // eg, var request = function (url, data) { return $.post(url, { json: JSON.stringify(data) }) }, settings = [ ["/echo/json/", "success1"], // `success` ["/echo/jsons/", "error1"], // `error` ["/echo/json/", "success2"], // `success` ["/echo/jsons/", "error2"], // `error` ["/echo/json/", "success3"] // `success` ]; $.when.all( $.map(settings, function (p) { return request.apply($, p) }) ) .then(function (data) { console.log(data); // filter , process responses $.each(data, function(key, value) { if (key === "success") { results.append( "\r\n" + key + ":\r\n" + JSON.stringify(value, null, 4) ) } else { results.append( "\r\n" + key + ":\r\n" + JSON.stringify( value.map(function(v, k) { v.data.responseText = $(v.data.responseText) .filter("title, #summary, #explanation") .text().replace(/\s+/g, " "); return v }) , null, 4) ) } }) }, function (e) { console.log("error", e) }); 

jsfiddle http://jsfiddle.net/guest271314/620p8q8h/