javascript - Jquery Ajax previene la falla en un bucle secuencial diferido
(1)
Entonces, estoy encadenando juntos ajax secuencial, para cargar una matriz de URL en orden.
Originalmente utilicé
.then()
lugar de
.always()
, y de cualquier manera funciona bien, siempre que existan todas las URL.
Sin embargo, dado que existe la posibilidad de que falten archivos, quería compensar eso y, finalmente, informar al usuario de qué archivos faltaban, para facilitar la rectificación.
Sin embargo, el problema es que, en un archivo / 404 faltante, el código se ejecuta, como debería, pero luego sale del bucle, evitando cualquier llamada ajax adicional.
Así que me imagino que necesito alguna forma de manejar el
fail()
y forzar un éxito independientemente, o alguna otra forma de anular el comportamiento predeterminado en un 404, para que continúe progresando a través del ciclo.
Desafortunadamente, los resultados más cercanos de Google fueron cómo hacer lo contrario (forzar un fracaso en el éxito).
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.
});
Una nota final, para aliviar la confusión: las URL y el script en sí están en un sitio de MediaWiki, por lo que incluso si se devuelve un 404, siempre habrá contenido de la página y contendrá el elemento con la identificación de "mw-content". -texto".
Tratar
(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)
});