2017-09-16 6 views
0

私は非同期に動作する保存関数を持っているので、私は約束を使用しています。メインの保存イベントが入り、特定のthencatchハンドラが1度だけ接続されます。私のコード例では、importantSaveメソッドで発生します。今度は、後に呼び出される他のセーブコールがいくつでも存在し、sideSaveメソッドを参照できます。すでに宣言されているPromiseチェーンを無効にすることはできますか?

側のすべてにimportantSave方法待ちでthencatchハンドラを作成する方法はありますが、彼らが最初に設定されているにもかかわらず、彼らが呼ばれる前に拒否/解決するために保存されますか?

例えば、私は、次のコードを持っている:

class Adapter { 
    promise; 
    next_attempt; 

    attempt() { 
     if (this.promise && this.promise.isPending()) { 
      this.next_attempt = this.attempt.bind(this); 
      return this.promise.then(()=> { 
       if (this.next_attempt) { 
        return this.next_attempt(); 
       } 
      }); 
     } else { 
      this.promise = new Promise(resolve=> { 
       setTimeout(resolve, 3000); 
      }); 

      return this.promise; 
     } 
    } 
} 
const adapter = new Adapter(); 

function importantSave() { 
    adapter.attempt() 
     .then(()=> { 
      console.log('Hello from the important save!'); 
     }); 
} 

function sideSave() { 
    adapter.attempt() 
     .then(()=> { 
      console.log('Hello from the side save!'); 
     }); 
} 

// the important save which sets up its then and catches, but wants to be called after all have finished 
importantSave(); 

// any number of side saves, but will only be called with the last side save 
sideSave(); 
sideSave(); 
sideSave(); 

はimportantSaveでthenが実際にsideSaveコールのいずれかのthens後に実行された場合にようにこれを変更する方法はありますか?私の実際の世界の例では、各呼び出しの間に遅延を伴うsave関数を3回呼び出し、3つがすべて失敗した場合にのみ拒否します。 3つすべてが失敗する前にsaveの別の呼び出しが発生した場合、私は最新の呼び出しを "next_attempt"にして、最初の呼び出しがまだ保留中であったときに他の呼び出しを上書きしようとします。元のコールが保存に失敗したが、「sideSave」コールの1つが成功した場合は、importantSaveを実行して元のコールが失敗したキャッチではなく、その時点まで落ちるようにします。

+0

注意を、それあなたが明らかに決して:

今、あなたは行うことができます。また、コードが 'isPending()'のようなものに依存するようにすることは悪い習慣であることに注意してください。 'then'や派生したメソッドを使う以外に、約束の状態をチェックする必要はありません。 – trincot

答えて

1

一般的なやり方はPromise.allです。

あなたは配列に解決し、それを引数として渡す必要があり、すべての約束を追加します。

Promise.all([importantSave(), sideSave(), sideSave(), sideSave()]).then(_ => { 
    console.log('all done'); 
}); 

あなたはもちろん、動的配列を作成することができます

var arr = [importantSave()]; 

arr.push(sideSave()); 
arr.push(sideSave()); 
arr.push(sideSave()); 

Promise.all(arr).then(_ => { 
    console.log('all done'); 
}); 

をあなただけのものにする必要がある場合それらの約束を逆に使ってください。

const invert = p => p.then(resp => { throw resp }).catch(err => err); 

この関数は、引数が満たされたときに拒否する約束を返し、逆も同様です。それはすでに値を持っているときに `this.next_attempt`を上書きします

var arr = [importantSave()]; 

arr.push(sideSave()); 
arr.push(sideSave()); 
arr.push(sideSave()); 

invert(Promise.all(arr.map(invert))).then(_ => { 
    console.log('one done'); 
}); 
+0

これは動作しません。たぶん私の記述は分かりにくいかもしれませんが、 'sideSaves'は動的に、私のコードのさまざまな領域から来ています。オリジナルの「then」を付ける前に、どれくらいのセーブが入るのか分かりません。これを視覚化するには、コードを想像してください: '' 'var arr = [importantSave()]; setTimeout(()=> { \t arr.push(sideSave()); }、1000); setTimeout(()=> { \t arr.push(sideSave()); }、2000); Promise.all(arr).then(_ => { \t console。log( 'すべて完了'); }); '' ' Promise.allはimportantSaveの後に直接解決されますが、ウィンドウタイムアウトのsideSavesは無視されます。 – jas7457

+0

はい、もちろん、あなたがまだ追加する人の数がわからないので、解決の約束を無視する必要があります。あなたの本当の約束は、Promise.allになります。あなたの質問はあまりにも曖昧です。あなたはあなたが待っていると言っているだけでなく、あなたが成就するとすぐに解決したいと言っているからです。 – trincot

+0

本当にあなたの必要は何ですか?操作を3回再試行し、すべてが失敗した場合にのみ諦めますか? * 3がすべて失敗した場合にのみ*が拒否されますので、なぜあなたは履行完了時にすべてを待っていますか? – trincot

関連する問題