因此,我将顺序的ajax链接在一起,以按顺序加载URL数组。最初,我使用.then()代替.always(),并且无论哪种方式都可以正常工作- 只要所有网址都存在。但是,由于可能会丢失文件,因此我想对此进行补偿,然后,最后通知用户丢失了哪些文件,以便更轻松地进行纠正。
.then()
.always()
但是,问题是,在丢失的文件/ 404上,代码会像应执行的那样执行,但随后退出循环,从而阻止了进一步的ajax调用。因此,我认为,我需要某种方式来处理fail()并强制执行成功,无论如何,还是需要某种其他方式来覆盖404上的默认行为,以便它在循环中继续进行。
fail()
不幸的是,最接近Google的结果是相反的做法(成功失败会导致失败)。
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 */] // }`
// e.g., 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/