w3schools then sincronas promises promesas funciones ejemplo anidadas javascript jquery asynchronous promise synchronous

javascript - then - jQuery Deferred and Promise para la ejecución secuencial de funciones síncronas y asíncronas



promise javascript ejemplo (3)

Si quiero que las funciones sincrónicas y asíncronas se ejecuten en un orden particular, podría usar la promesa de jQuery, pero no parece funcionar de la manera que esperaría que funcionara.

Las funciones a, byc deben ejecutarse en ese orden cuando en a deferred.resolve() Se llama a resuelve deferred.resolve() . Esperaría que se ejecutara la función b pero todas las funciones se ejecutan inmediatamente sin importar si se llama a la resolución.

Aquí está el código:

function a(){ var deferred = $.Deferred(); setTimeout(function(){ console.log("status in a:",deferred.state()); //this should trigger calling a or not? deferred.resolve("from a"); },200); console.log("a"); return deferred.promise(); }; function b(){ var deferred = $.Deferred(); setTimeout(function(){ console.log("status in b:",deferred.state()); deferred.resolve("from b"); },200); console.log("b"); return deferred.promise(); } //synchronous function function c(){ var deferred = $.Deferred(); console.log("c"); console.log("status in c:",deferred.state()); deferred.resolve("from c"); return deferred.promise(); } function test(){ fn=[a,b,c],i=-1, len = fn.length,d, d = jQuery.Deferred(), p=d.promise(); while(++i<len){ p=p.then(fn[i]); } p.then(function(){ console.log("done"); }, function(){ console.log("Failed"); }); d.resolve(); //instead of the loop doing the following has the same output //p.then(a).then(b).then(c); //d.resolve(); } test();

La salida es:

a b status in c: pending c done status in a: pending status in b: pending

Rendimiento esperado:

a status in a: pending b status in b: pending c status in c: pending done

Intenté algunas combinaciones de las siguientes modificaciones:

d = jQuery.Deferred(); setTimeout(function(){d.resolve();},100); var p=d.promise(); while(++i<len){ p.then(fn[i]); }

Pero todos con los mismos resultados inesperados, b se llama antes de que se resuelva el diferido de a, c se convoca antes de que se resuelva el diferido de b.


Para jQuery anterior a la 1.8, esto es un problema, pero para las nuevas versiones de jQuery, esto ya no es un problema:

function test(){ var d = jQuery.Deferred(), p=d.promise(); //You can chain jQuery promises using .then p.then(a).then(b).then(c); d.resolve(); } test();

MANIFESTACIÓN

Debajo está la demo de jQuery 1.7.2

MANIFESTACIÓN


jQuery <1.8 está bien encadenamiento WRT, solo usa .pipe lugar de .then . 1.8 simplemente cambió .then ser .pipe .


Nota: Cuando lo usas sin la matriz, no tienes que comenzar con una promesa. $.when({}).then(a).then(b) hará bien el truco. Solo necesita asegurarse de no colocar a when .