Jquery diferido No llega a último.

Tengo una secuencia de funciones que deben ejecutarse. Todos se ejecutan secuencialmente, excepto el último. d1 ejecuta, d2 ejecuta, d3 ejecuta y luego el código dentro de la function done se ejecuta antes de la resolución de d4. No puedo entender por qué. Cualquier ayuda sería apreciada.

$(document).ready(function() { var d1 = functiond1(); var d2 = functiond2(); var d3 = functiond3(); var d4 = functiond4(); d1.then(d2).then(d3).then(d4).done(function() { //Code here does not wait for d4 to end before executing //HELP! }); }); function functiond1() { var dfd = $.Defernetworking(); //Do stuff here //Works in sequence dfd.resolve(); return dfd.promise(); } function functiond2() { var dfd = $.Defernetworking(); params = jQuery.param({ 'parm1': 1, 'parm2': 2, 'parm3': 3 }); jQuery.getJSON($.webMethoJSONGet1, params).done(function(data) { //Do stuff here //Works in sequence dfd.resolve(); }); return dfd.promise(); } function functiond3() { var dfd = $.Defernetworking(); //Do stuff here //Works in sequence dfd.resolve(); return dfd.promise(); } function functiond4() { var dfd = $.Defernetworking(); params = jQuery.param({ 'parm1': 1, 'parm2': 2, 'parm3': 3 }); jQuery.getJSON($.webMethoJSONGet2, params).done(function(data) { //Do stuff here //does not work in sequence dfd.resolve(); }); return dfd.promise(); } 

Es difícil decir lo que estás tratando de hacer con esas promises. Primero llama a las 4 funciones y luego intenta encadenarlas con un montón de devoluciones de llamada. Si desea encadenarlas secuencialmente, debería verse así:

 functiond1() .then(functiond2) .then(functiond3) .then(functiond4) .done(function() { /* blah */ }); 

Si solo quiere un resultado después de que todos hayan terminado, puede usar $.when

 $.when(functiond1(), functiond2(), functiond3(), functiond4()) .then(function(resultd1, resultd2, resultd3, resultd4) { /* blah */ }); 

En otra nota, en sus funciones crea promises que se resuelven dentro de la callback done de otra promise que no es necesaria. Las $.getJSON.done() devuelven una promise, por lo que no se necesita una promise adicional. Simplemente devuelva la promise devuelta por done() .

Lo siento, no he alterado demasiado los objects diferidos de jQuery, pero parecen lo suficientemente similares a las promises estándar.

Para ejecutar las funciones en secuencia, necesita pasar references a las funciones dentro de la cadena .then , y no los resultados de llamar a esas funciones.

p.ej

 var d1 = functiond1; // NB: no () ... d1.then(d2).then(d3).then(d4).done(...); functiond1().then(functiond2).then(functiond3).then(functiond4).done(...) 

La causa principal de su problema es que si invoca d4 directamente, su promise resuelta pasará a .done inmediatamente, independientemente del estado de la parte anterior de la cadena .then .

Tampoco debe ajustar sus funciones JSON con promises adicionales, ya que $.getJSON ya devuelve una promise que será rechazada si la consulta AJAX falla:

 function functiond4() { ... return $.getJSON(...); } 

Estaba enfrentando el mismo problema en un proyecto, esta solución con una matriz funciona bien:

 $(document).ready(function() { var pr = []; var d1 = functiond1(); var d2 = functiond2(); var d3 = functiond3(); var d4 = functiond4(); function functiond1() { var dfd = $.Defernetworking(); pr.push(dfd); setTimeout(function(){ $('body').append('1 resolved <br>'); dfd.resolve(); }, 2000); } function functiond2() { var dfd = $.Defernetworking(); pr.push(dfd); params = jQuery.param({ 'parm1': 1, 'parm2': 2, 'parm3': 3 }); setTimeout(function(){ $('body').append('2 resolved <br>'); dfd.resolve(); }, 3000); } function functiond3() { var dfd = $.Defernetworking(); pr.push(dfd); setTimeout(function(){ $('body').append('3 resolved <br>'); dfd.resolve(); }, 1000); } function functiond4() { var dfd = $.Defernetworking(); pr.push(dfd); params = jQuery.param({ 'parm1': 1, 'parm2': 2, 'parm3': 3 }); setTimeout(function(){ $('body').append('4 resolved <br>'); dfd.resolve(); }, 50); } $.when.apply($, pr).then(function() { // do something $('body').append('proceed with code execution'); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>