私がより説明しようとする答えの2番目の試み:
まず、RSVP READMEからのいくつかの必要な背景:
本当に素晴らしい部分は、最初のハンドラーからpromiseを返すときに発生します...これにより、ネストされたコールバックをフラット化できます。これは、非同期コードが多いプログラムでの「右方向へのドリフト」を防ぐPromiseの主な機能です。
これはまさに、then
前に終了するはずのプロミスから後のプロミスを返すことによって、プロミスをシーケンシャルにする方法です。
このような一連のpromiseをツリーとして考えると役立ちます。ここで、ブランチは順次プロセスを表し、リーフは並行プロセスを表します。
このような約束のツリーを構築するプロセスは、他の種類のツリーを構築するという非常に一般的なタスクに類似しています。ツリー内の現在ブランチを追加している場所へのポインターまたは参照を維持し、繰り返し追加します。
@Esailijaが彼の回答で指摘したように、引数を取らないpromiseを返す関数の配列がある場合はreduce
、ツリーをきちんと構築するために使用できます。自分でreduceを実装したことがある場合は、@ Esailijaの回答の舞台裏でreduceが行っていることは、現在のpromise(cur
)への参照を維持し、各promiseに次のpromiseを返すことであることを理解できますthen
。
同種の(それらが取る/返す引数に関して)promise戻り関数の素晴らしい配列がない場合、または単純な線形シーケンスよりも複雑な構造が必要な場合は、次のようにしてpromiseのツリーを自分で構築できます。新しいPromiseを追加するPromiseツリー内の位置への参照:
var root_promise = current_promise = Ember.Deferred.create();
current_promise = current_promise.then(function(){
return
});
current_promise = current_promise.then(function(){
return
});
root_promise.resolve();
RSVP.allを使用して、promiseの「ブランチ」に複数の「リーフ」を追加することにより、並行プロセスと順次プロセスの組み合わせを構築できます。私のあまりにも複雑な答えは、その例を示しています。
また、Ember.run.scheduleOnce( 'afterRender')を使用して、次のプロミスが実行される前に、あるプロミスで行われた何かがレンダリングされるようにすることもできます。