Estoy aprendiendo a usar jQuery Deferred y estoy pensando en encadenar múltiples diferidos. Aquí hay una versión simplificada de mi problema:
var def1 = $.ajax(...); // ajax call 1 var def2 = null, def3 = null; $.when(def1) .then(function() { def2 = $.ajax(...); // ajax call 2 return def2; }).then(function() { def3 = $.ajax(...); // ajax call 3 return def3; });Luego, en algún lugar debajo del código anterior, tengo:
$.when(def1, def2, def3) .then(function() { // run some code... .eg run foo(); });El código anterior es incorrecto. No puede hacer lo que quiero. Mi intención real es básicamente:
Quiero ejecutar ajax call 1 primero.
Si la llamada 1 de ajax tiene éxito, ejecute la llamada 2 de ajax. (Sería una ventaja agregar: si la llamada 1 de ajax no tiene éxito y/o su resultado devuelto no pasa mi validación manual, avise al usuario y ejecute algún código , por ejemplo, barra().)
Si la llamada ajax 2 tiene éxito, ejecute la llamada ajax 3 (se aplica la misma bonificación)
Y luego quiero ejecutar algún código (por ejemplo, foo()) solo cuando se haya resuelto def3. Antes de ejecutar foo(), en realidad no me importa si def1 y def2 se han resuelto o no. (Si se rechaza def3, también quiero ejecutar otro fragmento de código, si es posible).
La razón por la que no puedo inicializar def2 (llamada ajax 2) y def3 (llamada ajax 3) al principio es que quiero modificar las opciones de la llamada ajax 2 según el resultado devuelto de la llamada ajax 1. De la misma manera para ajax call 3, dependiendo del resultado de ajax call 2.
Con mi conocimiento y comprensión limitados de diferido, el código anterior básicamente no puede producir lo que quiero.
Debido a que def1 se resuelve antes de que def2 se inicialice y active, por lo que la parte inferior del código ejecutará foo() demasiado pronto antes de que se inicie def2...
Por eso pido ayuda y consejo. Vea si alguien tiene alguna idea de cómo reescribir el código anterior y hacer que funcione como mi intención escrita anteriormente. Lo siento por mi incapacidad.
Gracias a todos de antemano.
No necesita usar when , que realmente se usa mejor cuando desea ejecutar múltiples diferidos en paralelo. Prueba esto:
var d1 = $.ajax(...); var d2 = d1.then(function () { if (invalid) { return $.Deferred().reject("Invalid"); } return $.ajax(...); }); var d3 = d2.then(function () { if (invalid) { return $.Deferred().reject("Invalid"); } return $.ajax(...); }); d3.done(function () { // This is called when we're all done. });Que podría simplificarse a esto:
$.ajax(...).then(function () { if (invalid) { return $.Deferred().reject("Invalid"); } return $.ajax(...); }).then(function () { if (invalid) { return $.Deferred().reject("Invalid"); } return $.ajax(...); }).done(function () { // This is called when we're all done. }) // Use this to handle failure. You can also add to individual // deferred objects to handle each failure differently. .fail(function () { // Do something. }); Para manejar las fallas, es posible que deba agregar otra devolución de llamada dentro de then :
.then(function () { if (invalid) { return $.Deferred().reject("Invalid"); } // Do stuff }, function (err) { })