約束が解決されると、ダイジェストループが呼び出されますか?
はい。簡単なテンプレートでこれをテストできます。
{{state}}
$scope.state
遅延後に変数を変更するコントローラーコード:
$scope.state = 'Pending';
var d = $q.defer();
d.promise.then(function() {
$scope.state = 'Resolved, and digest cycle must have run';
});
$window.setTimeout(function() {
d.resolve();
}, 1000);
これはhttp://plnkr.co/edit/fIfHYz9EYK14A5OS6NLd?p=previewで確認できます。1 秒後、HTML のテキストが表示されますResolved, and digest cycle must have run
。ダイジェスト ループを開始する最終的なものでなければならないことを保証するために、setTimeout
むしろ$timeout
意図的な呼び出しです。resolve
これは、ソースを調べることで確認されます: docsによると、 にコールバックを渡した関数である をresolve
介してそのコールバックを呼び出します:nextTick
$rootScope.$evalAsync
$evalAsync
式の実行後、少なくとも 1 つの $digest サイクルが実行されます
それらの同じドキュメントにも次のように書かれています。
注: この関数が $digest サイクルの外で呼び出された場合、新しい $digest サイクルがスケジュールされます
そのため、スタックが既に $digest ループにあるかどうかによって、イベントの正確な順序が変わる可能性があります。
'1. 説明した各ステップ/フェーズで発生する順序は何ですか?
前の例を詳しく見てみましょう。
var d = $q.defer();
遅延オブジェクトの promise は保留状態にあります。resolve
この時点では、実質的に何も起こっていません。 、reject
、notifiy
およびpromise
プロパティを持つ遅延オブジェクトがあるだけです。$digest ループを使用したり、影響を与えたりしたものはありません
d.promise.then(function() {
$scope.state = 'Resolved, and digest cycle must have run';
});
promise はまだ保留中の状態ですが、then
成功のコールバックが登録されています。繰り返しますが、$digest ループやスコープを使用したり、影響を与えたりするものはありません。
$window.setTimeout(function() {
d.resolve();
}, 1000);
1秒後d.resolve
に呼び出されます。これにより、上記の手順 2 で定義されたコールバックが$evalAsync に ( nextTick 経由で) 渡されます。
$evalAsync はコールバックを呼び出します
$evalAsync は、1 つの $digest サイクルが呼び出されることを保証します。
'2. 新しいpromiseインスタンスを持つ新しい遅延オブジェクトが作成されたとき-誰がそれを認識していますか/それは重要ですか?
の呼び出し元のみ$q.defer()
。resolved
が呼び出されるまで (または実際にはreject
または)、スコープに関しては何も起こりませんnotify
。
'3. スコープの更新されたプロミス オブジェクトがどの程度正確に解決されていますか? コールバック内で手動で更新する必要がありますか、またはダイジェストが自動的に呼び出され、ここで宣言されているように rootScope を更新します
前述のように、 $digest ループは呼び出しによって自動的に開始されますresolve
(まだ含まれていない場合)。
'4. promise コールバック内からスコープを更新する少なくとも 1 つのアプローチについて言及する
上記の例はこれを示しています。
'5. 他にもたくさんの便利な側面があると思いますが、それらすべてを自由に提供してください。
私が考えることができることではありません!