it-swarm.com.de

Was ist der Unterschied zwischen $ evalAsync und $ timeout in AngularJS?

Ich benutze AngularJS jetzt schon eine Weile und habe festgestellt, dass ich gelegentlich $ timeout verwenden muss (Scheint normalerweise, ein jQuery-Plugin zu starten).

Vor kurzem habe ich versucht, den Digest-Zyklus besser und gründlicher zu verstehen, und bin auf die Funktion $ evalAsync gestoßen.

Es scheint, dass diese Funktion ähnliche Ergebnisse wie $timeout Liefert, nur dass Sie sie nicht verzögern. Jedes Mal, wenn ich $timeout Verwendet habe, war die Verzögerung 0, und jetzt frage ich mich, ob ich stattdessen $evalAsync Hätte verwenden sollen.

Gibt es grundlegende Unterschiede zwischen den beiden? Welche Fälle würden Sie übereinander verwenden? Ich möchte ein besseres Gefühl dafür bekommen, wann ich welche verwenden soll.

177
dnc253

Ich habe kürzlich im Wesentlichen diese Frage hier beantwortet: https://stackoverflow.com/a/17239084/215945 (Diese Antwort verweist auf einige Github-Austausche mit Misko.)

Zusammenfassen:

  • wenn Code mit $ evalAsync aus einer Direktive in die Warteschlange gestellt wird , sollte er ausgeführt werden nach das DOM wurde von Angular manipuliert, aber vorher der browser rendert
  • wenn Code mit $ evalAsync von einem Controller in die Warteschlange gestellt wird , sollte er ausgeführt werden vorher Das DOM wurde von Angular (und bevor der Browser rendert) - selten möchten Sie dies
  • wenn Code mit $ timeout in die Warteschlange gestellt wird, sollte er ausgeführt werden after Das DOM wurde von Angular manipuliert, und after der Browser rendert (was in einigen Fällen zu Flimmern führen kann)
260
Mark Rajcok

Beachten Sie bei der Erstellung komplexer Anwendungen, dass sich dies auf die Leistung Ihrer Wahl auswirkt. Außerdem möchte ich Mark Antwort mit weiteren technischen Details vervollständigen:

  • $ timeout (Rückruf) wartet, bis der aktuelle Digest-Zyklus abgeschlossen ist (dh angular alle Modelle und die DOM), dann führt es seinen Rückruf aus - wirkt sich möglicherweise auf angular Modell aus - und startet dann ein vollständiges $apply auf dem Root-Bereich $, und verdauen Sie alles neu.

  • $ evalAsync (Rückruf) fügt den Rückruf hingegen zum aktuellen oder nächsten Digest-Zyklus hinzu. Das heißt, wenn Sie sich in einem Digest-Zyklus befinden (zum Beispiel in einer Funktion, die von einem ng-click Direktive), dies wird nicht auf irgendetwas warten, der Code wird sofort ausgeführt. Wenn Sie sich in einem asynchronen Aufruf befinden, z. B. ein setTimeout, ein neuer Digest-Zyklus ($apply) wird ausgelöst.

In Bezug auf die Leistungen ist es immer besser, $evalAsync, es sei denn, es ist für Sie wichtig, dass die Ansicht vor der Ausführung Ihres Codes auf dem neuesten Stand ist, zum Beispiel, wenn Sie Zugriff auf einige DOm-Attribute wie die Breite von Elementen und dergleichen benötigen.

Wenn Sie weitere Details zur Unterscheidung zwischen $ timeout, $ evalAsync, $ digest, $ apply wünschen, lade ich Sie ein, meine Antwort auf diese andere Frage zu lesen: https://stackoverflow.com/a/23102223/1501926

Lesen Sie auch unbedingt die Dokumentation :

$ EvalAsync gibt keine Garantie dafür, wann der Ausdruck ausgeführt wird, nur dass:

  • es wird nach der Funktion ausgeführt, die die Auswertung geplant hat (vorzugsweise vor dem DOM-Rendering).
  • nach der Ausführung des Ausdrucks wird mindestens ein $ digest-Zyklus ausgeführt.

Hinweis: Wenn diese Funktion außerhalb eines $ digest-Zyklus aufgerufen wird, wird ein neuer $ digest-Zyklus eingeplant . Es wird jedoch empfohlen, immer Code aufzurufen, der das Modell innerhalb eines $ apply-Aufrufs ändert. Dazu gehört auch Code, der über $ evalAsync ausgewertet wird.

57
floribon