Si necesito llamar a estas funciones una tras otra,
$('#art1').animate({'width':'1000px'},1000);
$('#art2').animate({'width':'1000px'},1000);
$('#art3').animate({'width':'1000px'},1000);
Sé que en jQuery podría hacer algo como:
$('#art1').animate({'width':'1000px'},1000,'linear',function(){
$('#art2').animate({'width':'1000px'},1000,'linear',function(){
$('#art3').animate({'width':'1000px'},1000);
});
});
Pero, supongamos que no estoy usando jQuery y quiero llamar:
some_3secs_function(some_value);
some_5secs_function(some_value);
some_8secs_function(some_value);
¿Cómo debo llamar a estas funciones para ejecutar some_3secs_function
, y DESPUÉS de que finalice la llamada, luego ejecutar some_5secs_function
y DESPUÉS de que finalice esa llamada, luego llamar some_8secs_function
?
ACTUALIZAR:
Esto todavía no funciona:
(function(callback){
$('#art1').animate({'width':'1000px'},1000);
callback();
})((function(callback2){
$('#art2').animate({'width':'1000px'},1000);
callback2();
})(function(){
$('#art3').animate({'width':'1000px'},1000);
}));
Tres animaciones comienzan al mismo tiempo
¿Dónde está mi error?
Respuestas:
En Javascript, hay funciones sincrónicas y asincrónicas .
Funciones sincrónicas
La mayoría de las funciones en Javascript son sincrónicas. Si tuviera que llamar a varias funciones síncronas seguidas
ellos ejecutarán en orden.
doSomethingElse
no comenzará hasta que sedoSomething
haya completado.doSomethingUsefulThisTime
, a su vez, no comenzará hasta que sedoSomethingElse
haya completado.Funciones asincrónicas
Sin embargo, la función asincrónica no se esperará la una a la otra. Veamos el mismo ejemplo de código que teníamos arriba, esta vez suponiendo que las funciones son asíncronas.
Las funciones se inicializarán en orden, pero todas se ejecutarán aproximadamente al mismo tiempo. No puede predecir constantemente cuál terminará primero: el que tarde menos tiempo en ejecutarse terminará primero.
Pero a veces, desea que las funciones que sean asíncronas se ejecuten en orden, y a veces desea que las funciones que sean sincrónicas se ejecuten de forma asíncrona. Afortunadamente, esto es posible con devoluciones de llamada y tiempos de espera, respectivamente.
Devoluciones de llamada
Supongamos que tenemos tres funciones asíncronas que queremos ejecutar en orden,
some_3secs_function
,some_5secs_function
, ysome_8secs_function
.Dado que las funciones se pueden pasar como argumentos en Javascript, puede pasar una función como devolución de llamada para que se ejecute después de que la función se haya completado.
Si creamos las funciones como esta
entonces puedes llamar en orden, así:
Tiempos de espera
En Javascript, puede indicarle a una función que se ejecute después de un cierto tiempo de espera (en milisegundos). De hecho, esto puede hacer que las funciones síncronas se comporten de forma asíncrona.
Si tenemos tres funciones sincrónicas, podemos ejecutarlas de forma asincrónica utilizando la
setTimeout
función.Sin embargo, esto es un poco feo y viola el principio DRY [wikipedia] . Podríamos limpiar esto un poco creando una función que acepte un conjunto de funciones y un tiempo de espera.
Esto se puede llamar así:
En resumen, si tiene funciones asincrónicas que desea ejecutar sincrónicamente, use devoluciones de llamada, y si tiene funciones sincrónicas que desea ejecutar de forma asincrónica, use tiempos de espera.
fuente
Esta respuesta utiliza
promises
, una característica de JavaScript delECMAScript 6
estándar. Si su plataforma de destino no es compatiblepromises
, complétela con PromiseJs .Mire mi respuesta aquí Espere hasta que una función con animaciones termine hasta ejecutar otra función si desea usar
jQuery
animaciones.Así es como se vería su código con
ES6 Promises
yjQuery animations
.Los métodos normales también se pueden envolver
Promises
.El
then
método se ejecuta tan pronto comoPromise
termine. Normalmente, el valor de retorno delfunction
pasadothen
se pasa al siguiente como resultado.Pero si
Promise
se devuelve a, la siguientethen
función espera hasta quePromise
finalice la ejecución y recibe los resultados (el valor al que se pasafulfill
).fuente
Parece que no estás apreciando completamente la diferencia entre síncrono y asíncrono ejecución de funciones .
El código que proporcionó en su actualización ejecuta inmediatamente cada una de sus funciones de devolución de llamada, que a su vez inicia inmediatamente una animación. Las animaciones, sin embargo, se ejecutan de forma asíncrona . Funciona así:
setTimeout
con una función que contiene el siguiente paso de animación y un retrasosetTimeout
ejecutaEsto continúa hasta que se complete el último paso en la animación. Mientras tanto, sus funciones síncronas se han completado hace mucho tiempo. En otras palabras, su llamada a la
animate
función realmente no toma 3 segundos. El efecto se simula con retrasos y devoluciones de llamada.Lo que necesitas es una cola . Internamente, jQuery pone en cola las animaciones, solo ejecutando su devolución de llamada una vez que se completa su animación correspondiente. Si su devolución de llamada inicia otra animación, el efecto es que se ejecutan en secuencia.
En el caso más simple, esto es equivalente a lo siguiente:
Aquí hay una función general de bucle asíncrono. Llamará a las funciones dadas en orden, esperando el número especificado de segundos entre cada una.
Uso:
Obviamente, podría modificar esto para tomar tiempos de espera configurables o ejecutar inmediatamente la primera función o detener la ejecución cuando una función en la cadena regrese
false
o aapply
las funciones en un contexto específico o cualquier otra cosa que pueda necesitar.fuente
Creo que la biblioteca asíncrona le proporcionará una forma muy elegante de hacer esto. Si bien las promesas y las devoluciones de llamada pueden ser un poco difíciles de hacer malabares, la sincronización puede proporcionar patrones claros para simplificar su proceso de pensamiento. Para ejecutar funciones en serie, deberá colocarlas en una cascada asíncrona . En la jerga asíncrona, cada función se llama a
task
que toma algunos argumentos y acallback
; cual es la siguiente función en la secuencia. La estructura básica se vería así:Acabo de intentar explicar brevemente la estructura aquí. Lea la guía de la cascada para obtener más información, está bastante bien escrita.
fuente
sus funciones deben tomar una función de devolución de llamada, que se llama cuando finaliza.
entonces el uso sería como:
fuente
No entraré en una discusión profunda sobre setTimeout aquí, pero:
fuente
Como lo etiquetó con javascript, usaría un control de temporizador ya que los nombres de sus funciones son 3, 5 y 8 segundos. Por lo tanto, inicie su temporizador, 3 segundos, llame al primero, 5 segundos al segundo, 8 segundos al tercero, y cuando termine, detenga el temporizador.
Normalmente, en Javascript, lo que tiene es correcto para que las funciones se ejecuten una tras otra, pero como parece que está tratando de hacer una animación programada, un temporizador sería su mejor opción.
fuente
fuente
next
?También podría usar promesas de esta manera:
Tendrías que hacer
some_value
global para acceder desde el interior de .thenAlternativamente, desde la función externa, podría devolver el valor que usaría la función interna, así:
fuente
Uso una función 'waitUntil' basada en setTimeout de javascript
Esto funcionaría perfectamente si sus funciones establecen una cierta condición en verdadera, que podría sondear. Además, viene con tiempos de espera, que le ofrecen alternativas en caso de que su función no haya podido hacer algo (incluso dentro del rango de tiempo. ¡Piense en los comentarios de los usuarios!)
p.ej
fuente
Si el método 1 tiene que ejecutarse después de los métodos 2, 3, 4. El siguiente fragmento de código puede ser la solución para esto usando el objeto diferido en JavaScript.
fuente