スコープ ウォッチャーとフィルターの両方がダイジェスト ループ内で繰り返し実行されることを理解しています。ただし、次のことは私には少しわかりません。
それらは同じサイクル数で実行されていますか?
両方とも同じ状況によって引き起こされますか?
スコープ ウォッチャーとフィルターの両方がダイジェスト ループ内で繰り返し実行されることを理解しています。ただし、次のことは私には少しわかりません。
それらは同じサイクル数で実行されていますか?
両方とも同じ状況によって引き起こされますか?
ウォッチはダイジェスト サイクルごとにチェックされます。そして、Angular 式$watch
を見ることができます。式の内部には、監視対象の式が変更されたかどうかを判断するために( を使用して) Angular が評価する必要があるフィルターが存在する場合があります。$interpolate
両方とも同じ状況によって引き起こされますか?
したがって、フィルタは によって直接実行される$digest
のではなく、 の結果として実行され$watch
ます。実際には、フィルターは監視された式の評価によってトリガーされます。
のパフォーマンスに関してフィルタが特に話題になる理由はいくつかあり$digest
ます。これらの 2 つの式を見ると、次のようになります。
式 1:{{searchText+2}}
式 2:{{searchText | myFilter:true}}
$digest
aがトリガーされるたびに、両方の式が評価されます。したがって、1 つのリスク領域は単純myFilter
に複雑であり、単純なものよりもはるかに多くのプロセッサ サイクルを使用することになります (上記の +2 のように)。
やや明白ではありませんが、フィルターがべき等でない場合、フィルターはすべてのウォッチャーの余分な実行を引き起こす可能性があります。$digest
いずれかのウォッチが変更をもたらす場合、ダーティ ビットが実行されるたびに設定されます。そして、そのダーティ ビットが設定されている場合は、すべての監視を再実行します。これにより、すべての変更が伝播されます。たとえばsearchText
、 がウォッチの 1 つによって変更された場合、Angular は他のすべてのウォッチャーに、結果が依存しているかどうか、searchText
したがって変更する必要があるかどうかを確認する機会を与える必要があります。
ここに、上記の式 1 と 2 の違いがあります。最悪のシナリオとして、myFilter
乱数を返すと想像してください。 $digest
実行すると、ウォッチを評価するときに変化が見られるため (フィルターの前の結果が新しい結果と一致しない)、ウォッチ リストを再度実行します。フィルタは乱数を返すため、結果が変更された可能性が非常に高く、さらに別の$digest
. などなど... Angularには、ウォッチリストを10回ループした後のストップが組み込まれています.10回の試行後に結果が安定しない場合は、何かが間違っているため、「エラー: 10 $digest()反復回数に達しました。中止します!"
それらは同じサイクル数で実行されていますか?
したがって、監視対象の各式 (フィルターを含む) は少なくとも ごとに 2 回実行され$digest
ます。1 回はトリガー$digest
された変更のため、もう 1 回はその結果が伝播する必要があるかどうかを確認するためです。その伝播の結果、何らかの変更があった場合、監視とフィルターは何も変更されなくなるまで再度実行されます。
そしてもちろん、監視されている複数の式が同じフィルターを使用している場合は、上記に従って各式に対してそのフィルターが実行されます。