Quelle est la différence entre $ evalAsync et $ timeout dans AngularJS?

J’utilise AngularJS depuis un petit moment maintenant, et j’ai trouvé qu’il était nécessaire d’utiliser $ timeout de temps en temps (cela semble être habituellement d’initialiser un plugin jQuery).

Récemment, j’ai essayé de mieux comprendre le cycle de digestion et j’ai découvert la fonction $ evalAsync .

Il semble que cette fonction produise des résultats similaires à $timeout , mais vous ne lui donnez pas de délai. Chaque fois que j’ai utilisé $timeout cela a été avec un retard de 0, alors je me demande si j’aurais dû utiliser $evalAsync place.

Y a-t-il des différences fondamentales entre les deux? Quels cas utiliseriez-vous l’un sur l’autre? Je voudrais avoir une meilleure idée de quand utiliser lequel.

J’ai récemment répondu essentiellement à cette question ici: https://stackoverflow.com/a/17239084/215945 (qui répond à certains échanges de github avec Misko.)

Résumer:

  • Si le code est mis en queue à l’aide de $ evalAsync à partir d’une directive , il doit être exécuté après la manipulation du DOM par Angular, mais avant que le navigateur ne le restitue.
  • si le code est mis en queue à l’aide de $ evalAsync à partir d’un contrôleur , il doit s’exécuter avant que le DOM n’ait été manipulé par Angular (et avant que le navigateur ne le rend) – rarement
  • si le code est mis en queue à l’aide de $ timeout , il doit s’exécuter après la manipulation du DOM par Angular et après le rendu du navigateur (ce qui peut provoquer un scintillement dans certains cas)

Pour ceux qui créent des applications complexes, sachez que votre choix a un impact sur les performances. Aussi, je voudrais compléter la réponse de Mark avec plus de détails techniques:

  • $ timeout (callback) attendra que le cycle de digestion en cours soit terminé (mise à jour angular de tous les modèles et DOM), puis il exécutera son rappel – affectant potentiellement le modèle angular – puis lancera un $apply complet sur la scope $ root, et redigest tout.

  • $ evalAsync (callback) , d’autre part, appenda le rappel au cycle de digestion actuel ou suivant. Ce qui signifie que si vous êtes dans un cycle de digestion (par exemple dans une fonction appelée depuis une directive ng-click ), cela n’attendra rien, le code sera exécuté immédiatement. Si vous vous trouvez dans un appel asynchrone, par exemple un setTimeout , un nouveau cycle de résumé ( $apply ) sera déclenché.

Donc, en termes de performances, il est toujours préférable d’appeler $evalAsync , sauf s’il est important que la vue soit à jour avant d’exécuter votre code, par exemple si vous avez besoin d’accéder à certains atsortingbuts tels que la largeur des éléments.

Si vous voulez plus de détails sur la distinction entre $ timeout, $ evalAsync, $ digest, $ apply, je vous invite à lire ma réponse sur cette autre question: https://stackoverflow.com/a/23102223/1501926

Veillez également à lire la documentation :

$ EvalAsync ne garantit pas que l’expression sera exécutée, mais seulement que:

  • il s’exécutera après la fonction qui a programmé l’évaluation (de préférence avant le rendu DOM).
  • au moins un cycle $ digest sera exécuté après l’exécution de l’expression.

Remarque: si cette fonction est appelée en dehors d’un cycle $ digest, un nouveau cycle $ digest sera programmé . Cependant, il est recommandé de toujours appeler le code qui modifie le modèle depuis un appel $ apply. Cela inclut le code évalué via $ evalAsync.