9

$q サービスはangularjs で非常に強力であり、非同期コードで私たちの生活を楽にしてくれます。

私はAngularを初めて使用しますが、遅延APIを使用することは私にとってそれほど新しいことではありません. 私How to useはドキュメントの一部に完全に同意していると言わなければなりません+ドキュメント内には非常に便利なリンクがあります+ソースもチェックアウトしました。

私の質問は、angular の deferred および promise API オブジェクトの内部部分に関するものですライフ サイクルの正確なフェーズは何ですか。また、どのように相互作用しますか。私の仮定は、約束が解決されると、ダイジェストループが呼び出されるということです??? はい・いいえ ?rootScope.Scope

次の側面のリストに関して、具体的に詳細な回答を提供できますか。

  1. 説明した各ステップ/フェーズで発生する順序は何ですか?
  2. 新しいpromiseインスタンスを持つ新しい遅延オブジェクトが作成されたとき-誰がそれを認識していますか/それは重要ですか?
  3. promise オブジェクトが解決されたときに、スコープはどのくらい正確に更新されましたか? コールバック内で手動で更新する必要がありますか、またはダイジェストが自動的に呼び出され、ここで宣言されているように rootScope を更新します
  4. promise コールバック内からスコープを更新する少なくとも 1 つのアプローチについて言及する
  5. 他にもたくさんの便利な側面があると思いますが、それらすべてを自由に提供してください。

ドキュメントまたはソースへの可能な限りの参照(自分で見つけることができなかったもの)とともに、最も詳細な回答を高く評価し、受け入れます。このトピックに関する以前の議論が見つからない場合は、リンクを投稿してください。

ps:この質問のより良いタイトルを提案することで役立つ人には+1してください。コメントに提案を追加してください。

乾杯!

4

2 に答える 2

8

約束が解決されると、ダイジェストループが呼び出されますか?

はい。簡単なテンプレートでこれをテストできます。

{{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. 説明した各ステップ/フェーズで発生する順序は何ですか?

前の例を詳しく見てみましょう。

  1. var d = $q.defer(); 遅延オブジェクトの promise は保留状態にあります。resolveこの時点では、実質的に何も起こっていません。 、rejectnotifiyおよびpromiseプロパティを持つ遅延オブジェクトがあるだけです。$digest ループを使用したり、影響を与えたりしたものはありません

  2. d.promise.then(function() { $scope.state = 'Resolved, and digest cycle must have run'; });

    promise はまだ保留中の状態ですが、then成功のコールバックが登録されています。繰り返しますが、$digest ループやスコープを使用したり、影響を与えたりするものはありません。

  3. $window.setTimeout(function() { d.resolve(); }, 1000);

    1秒後d.resolveに呼び出されます。これにより、上記の手順 2 で定義されたコールバックが$evalAsync に ( nextTick 経由で) 渡されます。

  4. $evalAsync はコールバックを呼び出します

  5. $evalAsync は、1 つの $digest サイクルが呼び出されることを保証します。


'2. 新しいpromiseインスタンスを持つ新しい遅延オブジェクトが作成されたとき-誰がそれを認識していますか/それは重要ですか?

の呼び出し元のみ$q.defer()resolvedが呼び出されるまで (または実際にはrejectまたは)、スコープに関しては何も起こりませんnotify


'3. スコープの更新されたプロミス オブジェクトがどの程度正確に解決されていますか? コールバック内で手動で更新する必要がありますか、またはダイジェストが自動的に呼び出され、ここで宣言されているように rootScope を更新します

前述のように、 $digest ループは呼び出しによって自動的に開始されますresolve(まだ含まれていない場合)。


'4. promise コールバック内からスコープを更新する少なくとも 1 つのアプローチについて言及する

上記の例はこれを示しています。


'5. 他にもたくさんの便利な側面があると思いますが、それらすべてを自由に提供してください。

私が考えることができることではありません!

于 2014-04-29T13:00:22.693 に答える