¿Cuál es la diferencia entre $evalAsync y $timeout en AngularJS?

Resuelto dnc253 asked hace 11 años • 2 respuestas

He estado usando AngularJS por un tiempo y encontré la necesidad de usar $timeout de vez en cuando (parece que generalmente es para iniciar un complemento jQuery).

Recientemente, he estado tratando de obtener una comprensión mejor y más profunda del ciclo de resumen y encontré la función $evalAsync .

Parece que esa función produce resultados similares a $timeout, solo que no le das demora. Cada vez que $timeoutlo he usado ha sido con un retraso de 0, así que ahora me pregunto si debería haberlo usado $evalAsyncen su lugar.

¿Existen diferencias fundamentales entre los dos? ¿En qué casos usarías uno sobre el otro? Me gustaría tener una mejor idea de cuándo usar cuál.

dnc253 avatar Jun 25 '13 22:06 dnc253
Aceptado

Recientemente respondí esencialmente esta pregunta aquí: https://stackoverflow.com/a/17239084/215945 (Esa respuesta enlaza con algunos intercambios de github con Misko).

Para resumir:

  • Si el código está en cola usando $evalAsync de una directiva , debería ejecutarse después de que Angular haya manipulado el DOM, pero antes de que el navegador procese.
  • Si el código está en cola usando $evalAsync desde un controlador , debería ejecutarse antes de que Angular haya manipulado el DOM (y antes de que el navegador lo procese); rara vez desea esto
  • si el código está en cola usando $timeout , debe ejecutarse después de que Angular haya manipulado el DOM y después de que el navegador se procese (lo que puede causar parpadeos en algunos casos)
Mark Rajcok avatar Jun 25 '2013 17:06 Mark Rajcok

Para aquellos que crean aplicaciones complejas, tengan en cuenta que su elección tendrá un impacto en el rendimiento. Además, me gustaría completar la respuesta de Mark con más detalles técnicos:

  • $timeout(callback) esperará a que finalice el ciclo de resumen actual (es decir, actualización angular de todos los modelos y el DOM), luego ejecutará su devolución de llamada, lo que podría afectar el modelo angular, luego iniciará un $apply$scope completo en la raíz y volverá a digerir todo.

  • $evalAsync(callback) , por otro lado, agregará la devolución de llamada al ciclo de resumen actual o siguiente. Lo que significa que si estás dentro de un ciclo de resumen (por ejemplo, en una función llamada desde alguna ng-clickdirectiva), esto no esperará nada, el código se ejecutará de inmediato. Si se encuentra dentro de una llamada asincrónica, por ejemplo a , se activará setTimeoutun nuevo ciclo de resumen ( ).$apply

Entonces, en términos de rendimiento, siempre es mejor llamar a $evalAsync, a menos que sea importante para usted que la vista esté actualizada antes de ejecutar su código, por ejemplo si necesita acceso a algún atributo DOm como el ancho de los elementos y similares.

Si quieres más detalles sobre la distinción entre $timeout, $evalAsync, $digest, $apply, te invito a leer mi respuesta a esa otra pregunta: https://stackoverflow.com/a/23102223/1501926

También asegúrese de leer la documentación :

$evalAsync no garantiza cuándo se ejecutará la expresión, solo eso:

  • se ejecutará después de la función que programó la evaluación (preferiblemente antes de la representación DOM).
  • Se realizará al menos un ciclo $digest después de la ejecución de la expresión.

Nota: si esta función se llama fuera de un ciclo de $digest, se programará un nuevo ciclo de $digest . Sin embargo, se recomienda llamar siempre al código que cambie el modelo desde una llamada $apply. Eso incluye el código evaluado a través de $evalAsync.

floribon avatar Feb 03 '2015 00:02 floribon