example español await async another after javascript asynchronous jquery-deferred

javascript - español - ¿Cómo encadeno una secuencia de funciones diferidas en jQuery 1.8.x?



jquery deferred example (3)

Teniendo en cuenta estas funciones:

function func1() { var dfd = $.Deferred(); setTimeout(function() { dfd.resolve(''Password''); }, 1000); return dfd.promise(); } function func2(message) { var dfd = $.Deferred(); setTimeout(function() { if (message == ''Password'') { dfd.resolve(''Hello World''); } }, 1000); return dfd.promise(); }

Me gustaría encontrar una mejor manera de hacer lo siguiente. Tenga en cuenta que esto está usando jQuery 1.8.x.

var promise = func1(); promise.done(function(message1) { var promise2 = func2(message1); promise2.done(function(message2) { alert(message2); }); });

¿Algunas ideas? Pensé que usar jQuery #pipe o #then funcionaría, pero no puedo entenderlo. Aquí hay un violín para jugar: http://jsfiddle.net/Z7prn/


No es tan complicado (ya sea usar .then o .pipe , ambos son iguales desde jQuery 1.8, creo).

promise.then(func2).done(function(message) { alert(message); });

Como func2 devuelve un nuevo objeto diferido, la .done llamada .done se adjunta a ese lugar.

DEMO


Tuve un caso de uso similar, así que creo que esto debería ayudarte.

El siguiente método tomará una serie de métodos (que pueden o no devolver Promesas) y los ejecutará en secuencia, esperando hasta que se complete cada aplazamiento antes de continuar. El comportamiento predeterminado es detenerse en caso de fallo; El segundo argumento le permite continuar si la llamada falla o no.

las firmas de controlador de hecho / fallar son (Array < contexto >) Función (Array <Objeto {rechazado | resuelto: argumentos }>), donde contexto es el contexto de cada resolución con llamada / rechazo con llamada, o el diferido en cuestión, y argumentos es el argumento Conjunto que se pasó en la resolución / rechazo.

(function ($) { "use strict"; var copy = function (a) { return Array.prototype.slice.call(a); }; /** Handle a sequence of methods, stopping on failure by default @param Array<Function> chain List of methods to execute. Non-deferred return values will be treated as successful deferreds. @param Boolean continueOnFailure Continue executing even if one of the returned deferreds fails. @returns Deferred */ $.sequence = function (chain, continueOnFailure) { var handleStep, handleResult, steps = copy(chain), def = new $.Deferred(), defs = [], results = []; handleStep = function () { if (!steps.length) { def.resolveWith(defs, [ results ]); return; } var step = steps.shift(), result = step(); handleResult( $.when(result).always(function () { defs.push(this); }).done(function () { results.push({ resolved: copy(arguments) }); }).fail(function () { results.push({ rejected: copy(arguments) }); }) ); }; handleResult = continueOnFailure ? function (result) { result.always(function () { handleStep(); }); } : function (result) { result.done(handleStep) .fail(function () { def.rejectWith(defs, [ results ]); }); }; handleStep(); return def.promise(); }; }(this.jQuery));

Un ejemplo simple de uso: http://jsfiddle.net/rG9rA/

function func1() { var dfd = $.Deferred(); setTimeout(function() { dfd.resolve(''Password''); }, 1000); return dfd.promise(); } function func2(message) { var dfd = $.Deferred(); setTimeout(function() { if (message == ''Password'') { dfd.resolve(''Hello World''); } }, 1000); return dfd.promise(); } $.sequence([func1, func2, function () { alert(''done''); }]);


Utilice JQuery.when() . Es exactamente lo que desea encadenar a una serie de aplazados y ejecutar una función cuando todos hayan terminado.

Actualización 2017 (después de ver downvotes):

Lo que quería OP era una versión mejorada de su código para ejecutar promesas secuencialmente. Aquí está mi versión usando $.when :

function func1() { var dfd = $.Deferred(); setTimeout(function() { dfd.resolve(''Password''); }, 1000); return dfd.promise(); } function func2(message) { var dfd = $.Deferred(); setTimeout(function() { if (message == ''Password'') { dfd.resolve(''Hello World''); } }, 1000); return dfd.promise(); } // ~~~~~~~~~~ using $.when here ~~~~~~~~~~~~ $.when(func1()).then(function(result1) { $.when(func2(result1)).then(function(result2) { alert(result2); }) });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>