Ich versuche, die Nuancen der Verwendung des $ timeout-Dienstes in Angular als eine Art "sichere $ apply" -Methode besser zu verstehen. Grundsätzlich in Szenarien, in denen ein Code als Reaktion auf ein Angular-Ereignis oder ein Nicht-Angular-Ereignis wie jQuery oder ein Standard-DOM-Ereignis ausgeführt werden kann.
So wie ich die Dinge verstehe:
- Das Umschließen von Code in $ scope. $ Apply funktioniert gut in Szenarien, in denen Sie sich nicht bereits in einer Digest-Schleife befinden (auch bekannt als jQuery-Ereignis), aber einen Fehler auslösen, wenn ein Digest ausgeführt wird
- Das Umschließen von Code in einen $ timeout () -Aufruf ohne Verzögerungsparameter funktioniert unabhängig davon, ob er sich bereits in einem Digestzyklus befindet oder nicht
Wenn Sie sich den Angular-Quellcode ansehen, sieht es so aus, als würde $ timeout $ rootScope aufrufen. $ Apply ().
- Warum löst $ timeout () nicht auch einen Fehler aus, wenn bereits ein Digest-Zyklus ausgeführt wird?
- Ist es die beste Vorgehensweise, $ scope. $ Apply () zu verwenden, wenn Sie sicher sind, dass ein Digest noch nicht ausgeführt wird, und $ timeout (), wenn Sie es benötigen, um in beiden Fällen sicher zu sein?
- Ist $ timeout () wirklich eine akzeptable "sichere Anwendung" oder gibt es Fallstricke?
Vielen Dank für jeden Einblick.
$timeout
anstatt$apply
? Wenn Sie keinen Code freigeben können, können Sie zumindest den Grund dafür diskutieren?Wenn wir $ apply in der Anwendung stark verwenden, wird möglicherweise der Fehler: $ Digest bereits ausgeführt. Dies liegt daran, dass jeweils ein $ Digest-Zyklus ausgeführt werden kann. Wir können es durch $ timeout oder $ evalAsync beheben.
Das $ timeout generiert keinen Fehler wie "$ Digest ist bereits in Bearbeitung", da $ timeout Angular mitteilt, dass nach dem aktuellen Zyklus ein Timeout wartet und auf diese Weise sichergestellt wird, dass keine Kollisionen zwischen den Digest-Zyklen und damit der Ausgabe von $ auftreten Das Timeout wird in einem neuen $ Digest-Zyklus ausgeführt.
Ich habe versucht, sie zu erklären unter: Vergleich von Apply, Timeout, Digest und EvalAsync .
Vielleicht hilft es Ihnen.
quelle
Soweit ich es verstehe,
$timeout
handelt es sich um einen Wrapper, umsetTimeout
den implizit aufgerufen wird$scope.$apply
, dh er läuft außerhalb des Winkellebenszyklus, startet jedoch den Winkellebenszyklus selbst. Der einzige „Gotcha“ kann ich mir vorstellen, dass , wenn Sie erwarten , Ihr Ergebnis verfügbar sein dies$digest
, Sie müssen einen anderen Weg finden , um „sichere Anwendung“ (was AFAIK, nur über verfügbar ist$scope.$$phase
).quelle