unos una tiempo termine segundos que otra funcion esperar ejecutar despues automaticamente javascript jquery callback

javascript - tiempo - Espere hasta que una Función con animaciones finalice hasta ejecutar otra Función



setinterval javascript (8)

Tengo un problema con las funciones normales (que no son Ajax ) que implican muchas animaciones dentro de cada una de ellas. Actualmente simplemente tengo un setTimeout entre funciones, pero esto no es perfecto ya que ningún navegador / computadora es el mismo.

Nota adicional: ambos tienen animaciones separadas / etc. que colisionan.

No puedo simplemente poner uno en la función de devolución de llamada de otro

// multiple dom animations / etc FunctionOne(); // What I -was- doing to wait till running the next function filled // with animations, etc setTimeout(function () { FunctionTwo(); // other dom animations (some triggering on previous ones) }, 1000);

¿Hay alguna forma en js / jQuery de tener:

// Pseudo-code -do FunctionOne() -when finished :: run -> FunctionTwo()

Sé acerca de $.when() y $.done() , pero esos son para AJAX ...

  • MI SOLUCIÓN ACTUALIZADA

jQuery tiene una variable expuesta (que por algún motivo no figura en ninguna parte de los documentos jQuery) llamada $ .timers, que contiene la matriz de animaciones que se está llevando a cabo actualmente.

function animationsTest (callback) { // Test if ANY/ALL page animations are currently active var testAnimationInterval = setInterval(function () { if (! $.timers.length) { // any page animations finished clearInterval(testAnimationInterval); callback(); } }, 25); };

Uso básico:

// run some function with animations etc functionWithAnimations(); animationsTest(function () { // <-- this will run once all the above animations are finished // your callback (things to do after all animations are done) runNextAnimations(); });


Esta respuesta usa promises , una característica de JavaScript del estándar ECMAScript 6 . Si su plataforma objetivo no es compatible con las promises , PromiseJs con PromiseJs .

Puede obtener el objeto Deferred que jQuery crea para la animación utilizando .promise() en la llamada de animación. Envolver estos Deferreds en promises da como resultado un código mucho más limpio que el uso de temporizadores.

También puede usar Deferreds directamente, pero esto generalmente se desalienta porque no cumplen con la especificación Promises / A +.

El código resultante sería así:

var p1 = Promise.resolve($(''#Content'').animate({ opacity: 0.5 }, { duration: 500, queue: false }).promise()); var p2 = Promise.resolve($(''#Content'').animate({ marginLeft: "-100px" }, { duration: 2000, queue: false }).promise()); Promise.all([p1, p2]).then(function () { return $(''#Content'').animate({ width: 0 }, { duration: 500, queue: false }).promise(); });

Tenga en cuenta que la función en Promise.all() devuelve la promesa. Aquí es donde sucede la magia. Si en una llamada en then se devuelve una promesa, la siguiente llamada esperará a que esa promesa se resuelva antes de ejecutarse.

jQuery usa una cola de animación para cada elemento. Entonces, las animaciones en el mismo elemento se ejecutan sincrónicamente. ¡En este caso no tendrías que usar promesas en absoluto!

Inhabilité la cola de animación jQuery para demostrar cómo funcionaría con las promesas.

Promise.all() toma una serie de promesas y crea una nueva Promise que finaliza después de que finalicen todas las promesas en la matriz.

Promise.race() también toma una serie de promesas, pero termina tan pronto como termina la primera Promise .


Aquí hay una solución para n-calls (función recursiva). https://jsfiddle.net/mathew11/5f3mu0f4/7/

function myFunction(array){ var r = $.Deferred(); if(array.length == 0){ r.resolve(); return r; } var element = array.shift(); // async task timer = setTimeout(function(){ $("a").text($("a").text()+ " " + element); var resolving = function(){ r.resolve(); } myFunction(array).done(resolving); }, 500); return r; } //Starting the function var myArray = ["Hi", "that''s", "just", "a", "test"]; var alerting = function (){window.alert("finished!")}; myFunction(myArray).done(alerting);


Esto es lo que quieres decir con el hombre: http://jsfiddle.net/LF75a/

Tendrás una función activando la siguiente función y así sucesivamente, es decir, agrega otra llamada a función y luego agrega tu functionONe en la parte inferior.

Por favor déjame saber si me he perdido algo, espero que se ajuste a la causa :)

o esto: Llamar a una función después de que se haya completado la función anterior

Código:

function hulk() { // do some stuff... } function simpsons() { // do some stuff... hulk(); } function thor() { // do some stuff... simpsons(); }


Junto con la respuesta de Yoshi, encontré otra solución muy simple (tipo de devolución de llamada) para animaciones.

jQuery tiene una variable expuesta (que por algún motivo no figura en ninguna parte de los documentos jQuery) llamada $ .timers , que contiene la matriz de animaciones que se está llevando a cabo actualmente.

function animationsTest (callback) { // Test if ANY/ALL page animations are currently active var testAnimationInterval = setInterval(function () { if (! $.timers.length) { // any page animations finished clearInterval(testAnimationInterval); callback(); } }, 25); };

Uso básico:

functionOne(); // one with animations animationsTest(functionTwo);

Espero que esto ayude a algunas personas!


Puede usar jQuery $.Deferred

var FunctionOne = function () { // create a deferred object var r = $.Deferred(); // do whatever you want (e.g. ajax/animations other asyc tasks) setTimeout(function () { // and call `resolve` on the deferred object, once you''re done r.resolve(); }, 2500); // return the deferred object return r; }; // define FunctionTwo as needed var FunctionTwo = function () { console.log(''FunctionTwo''); }; // call FunctionOne and use the `done` method // with `FunctionTwo` as it''s parameter FunctionOne().done(FunctionTwo);

también puedes empacar múltiples diferidos juntos:

var FunctionOne = function () { var a = $.Deferred(), b = $.Deferred(); // some fake asyc task setTimeout(function () { console.log(''a done''); a.resolve(); }, Math.random() * 4000); // some other fake asyc task setTimeout(function () { console.log(''b done''); b.resolve(); }, Math.random() * 4000); return $.Deferred(function (def) { $.when(a, b).done(function () { def.resolve(); }); }); };

http://jsfiddle.net/p22dK/


Puedes hacerlo a través de la función de devolución de llamada.

$(''a.button'').click(function(){ if (condition == ''true''){ function1(someVariable, function() { function2(someOtherVariable); }); } else { doThis(someVariable); } });

function function1 (param, callback) {... hacer cosas callback (); }


agregue lo siguiente al final de la primera función

return $.Deferred().resolve();

llamar a ambas funciones como tal

functionOne().done(functionTwo);


ACTUALIZACIÓN DE ECMAScript 6

Esto usa una nueva característica de JavaScript llamada Promises

functionOne (). then (functionTwo);