Tengo una aplicación que requiere que los datos se carguen en un cierto orden: la URL raíz, luego los esquemas, luego finalmente inicialice la aplicación con los esquemas y las URL para los diversos objetos de datos. A medida que el usuario navega por la aplicación, los objetos de datos se cargan, validan contra el esquema y se muestran. A medida que el usuario CRUD los datos, los esquemas proporcionan validación de primer paso.
Tengo un problema con la inicialización. Utilizo una llamada Ajax para recuperar el objeto raíz, $ .when (), y luego creo una serie de promesas, una para cada objeto de esquema. Eso funciona. Veo la búsqueda en la consola.
Luego veo la búsqueda de todos los esquemas, por lo que cada llamada $ .ajax () funciona. fetchschemas () de hecho devuelve una serie de promesas.
Sin embargo, esa última cláusula when () nunca se activa y la palabra "DONE" nunca aparece en la consola. El código fuente de jquery-1.5 parece implicar que "nulo" es aceptable como un objeto para pasar a $ .when.apply (), como cuando () construirá un objeto interno diferido () para administrar la lista si no hay ningún objeto aprobada en.
Esto funcionó usando Futures.js. ¿Cómo se debe gestionar una matriz de jQuery Deferreds, si no es así?
var fetch_schemas, fetch_root;
fetch_schemas = function(schema_urls) {
var fetch_one = function(url) {
return $.ajax({
url: url,
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
return $.map(schema_urls, fetch_one);
};
fetch_root = function() {
return $.ajax({
url: BASE_URL,
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
$.when(fetch_root()).then(function(data) {
var promises = fetch_schemas(data.schema_urls);
$.when.apply(null, promises).then(function(schemas) {
console.log("DONE", this, schemas);
});
});
fuente
Respuestas:
Estas buscando
Esto también funcionará (por algún valor de trabajo, no reparará ajax roto):
Querrás pasar en
$
lugar denull
para quethis
dentro se$.when
refierajQuery
. No debería importar a la fuente, pero es mejor que pasarnull
.Se burló de todos sus $ .ajax reemplazándolos con
$.when
y la muestra funcionaPor lo tanto, es un problema en su solicitud ajax o la matriz que pasa a fetch_schemas.
fuente
.then(a,b) === .done(a).fail(b)
es una taquigrafía perezosa. Puedes llamar.done(a).fail(b)
si quieres$.when.apply($, ...
. Elnull
me hace ir "espera, ¿qué?". Es una cuestión de estilo y práctica de codificación. Tuve que leer la fuente para confirmarthis
que no arrojaría una referencia nula dentro de jQuery.cuando!La solución anterior (¡gracias!) No aborda adecuadamente el problema de recuperar los objetos proporcionados al
resolve()
método diferido porque jQuery llama adone()
yfail()
devoluciones de llamada con parámetros individuales, no una matriz. Eso significa que tenemos que usar laarguments
pseudo-matriz para obtener todos los objetos resueltos / rechazados devueltos por la matriz de diferidos, lo cual es feo:Como aprobamos una serie de diferidos, sería bueno obtener una variedad de resultados. También sería bueno recuperar una matriz real en lugar de una pseudo-matriz para que podamos usar métodos como
Array.sort()
.Aquí hay una solución inspirada en el método de when.js
when.all()
que aborda estos problemas:Ahora puede simplemente pasar una matriz de diferidos / promesas y recuperar una matriz de objetos resueltos / rechazados en su devolución de llamada, de esta manera:
fuente
apply()
... imagínense.arguments
manipulación oculta en su propio método. Genial para la reutilización, pero no aborda la "fealdad" de tener que lidiararguments
(fácilmente podría haber simplemente:var schemas=Array.prototype.slice.call(arguments);)
deferred.fail(...)
leerdeferred.reject(...)
?Si está utilizando la versión ES6 de javascript Hay un operador de propagación (...) que convierte la matriz de objetos en argumentos separados por comas.
Más información sobre el operador de propagación ES6 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator encontrar aquí
fuente
se extiende cuando con este código:
fuente