181

私は AngularJS をしばらく使用してきましたが、時々$timeoutを使用する必要があることがわかりました(通常は jQuery プラグインを初期化する必要があるようです)。

最近、私はダイジェスト サイクルをより深く理解しようとしており、$evalAsync関数に出会いました。

その関数は と同様の結果を生成するよう$timeoutですが、遅延を与えないだけです。使用するたびに$timeout遅延が0だったので、代わりに使用する必要があったかどうか疑問に思ってい$evalAsyncます。

両者の間に根本的な違いはありますか?どちらのケースを使用しますか? どちらをいつ使うべきか、より良い感覚を得たいと思います。

4

2 に答える 2

267

私は最近、本質的にこの質問に答えました: https://stackoverflow.com/a/17239084/215945 (その答えは、Misko との github 交換へのリンクです。)

要約する:

  • コードがディレクティブから $evalAsyncを使用してキューに入れられた場合、DOM が Angular によって操作された、ブラウザーがレンダリングする前に実行する必要があります。
  • コードがコントローラから $evalAsyncを使用してキューに入れられた場合、DOM が Angular によって操作される前 (およびブラウザがレンダリングされる) に実行する必要があります。これが必要になることはめったにありません。
  • コードが$timeoutを使用してキューに入れられた場合、DOM が Angular によって操作された後、およびブラウザーがレンダリングされたに実行する必要があります(場合によってはちらつきが発生する可能性があります)。
于 2013-06-25T17:29:51.783 に答える
59

複雑なアプリケーションを構築する場合は、選択によってパフォーマンスに影響があることに注意してください。また、より技術的な詳細でマークの回答を完成させたいと思います。

  • $timeout(callback)は、現在のダイジェスト サイクルが完了するまで待機し (つまり、すべてのモデルと DOM の角度更新)、そのコールバックを実行します (角度モデルに影響を与える可能性があります)。次に$apply、ルート $scope でフルを起動し、再ダイジェストします。すべての。

  • 一方、 $evalAsync(callback)は、コールバックを現在または次のダイジェスト サイクルに追加します。つまり、ダイジェスト サイクル内 (たとえば、ng-clickディレクティブから呼び出される関数内) にいる場合、これは何も待機せず、コードはすぐに実行されます。たとえば のような非同期呼び出し内にいる場合setTimeout、新しいダイジェスト サイクル ( $apply) がトリガーされます。

したがって、パフォーマンスの観点から$evalAsyncは、コードを実行する前にビューが最新であることが重要でない限り、常に を呼び出す方が良いです。たとえば、要素の幅などの DOm 属性にアクセスする必要がある場合などです。

$timeout、$evalAsync、$digest、$apply の違いについて詳しく知りたい場合は、他の質問に関する私の回答をお読みください: https://stackoverflow.com/a/23102223/1501926

また、必ずドキュメントを読んでください:

$evalAsync は、式がいつ実行されるかについて保証しません。

  • 評価をスケジュールした関数の後 (できれば DOM レンダリングの前) に実行されます。
  • 式の実行後、少なくとも 1 つの $digest サイクルが実行されます。

注:この関数が $digest サイクルの外で呼び出されると、新しい $digest サイクルがスケジュールされます。ただし、$apply 呼び出し内からモデルを変更するコードを常に呼び出すことをお勧めします。これには、$evalAsync を介して評価されるコードが含まれます。

于 2015-02-03T00:10:22.847 に答える