2017-01-03 2 views
0

私はお互いに独立した2つの約束を持っており、の約束が完了した後に最後のステップをしたいと思っています(拒否または解決)。AngularJSの複数の約束のためにsingle finallyハンドラを持つ方法は?

の$ q.all()私は最終的にはいつも約束のいずれかが

一つの解決策はカウンターを持っていると持っている可能性が拒否しても、(一度だけ、両方の約束のために)実行するとして使用することはできませんfinallyHandlerは、両方の約束が解決/拒否されたときにそれを実行する関数です。

var count = 0; 
    function finallyHandler() { 
    if (++count === 2) { 
     doStuff(); 
     count = 0; 
     } 
    } 

firstPromise.finally(finallyHandler); 
secondPromise.finally(finallyHandler); 

これが動作することができますが、右には見えません。

これを行うにはさらに良い方法はありますか?

+1

解決済みか拒否のどちらが解決されるのか?コードを読みやすく、扱いやすくします。 – briosheje

+0

@brioshejeは正しいアイデアを持っています。それぞれが独自のパススルー・エラーの振る舞いを持つように、約束の配列を構築する。 'promises.push(doStuff()。catch(e => e))' 'Promise.allを' promises'に適用します。 – danh

答えて

0

通常、$q.allは、拒否され、他の約束を待たない最初の約束で拒否されます。全てが満たさまたは拒否解決することを約束を待つために、それぞれの約束のresiliantバージョンを作成し、それらの上$q.all使用:.catchメソッドに値を戻すことにより

var resiliantFirstPromise = firstPromise.catch(e => "CONVERTED"); 
var resiliantSecondPromise = secondPromise.catch(e => "CONVERTED"); 

$q.all([resiliantFirstPromise, resiliantSecondPromise]) 
    .then(() => { 
    console.log("Both promises have resolved"); 
}); 

を、拒否された各約束は派生約束を返します。 は、約束通りに変換されています。派生した約束は拒否されないので、$q.allは両方の約束が解決されるのを待つ(成立したか拒絶されたか)。

+0

に更新しましたこれはきれいに見え、うまくいきます!私は**解決する**両方の約束が**部分**と混同されているように**解決**はしばしば**達成された**を意味します。 – Hemant

+0

私は一部の人々が*解決済み*を意味して*解決済み*を意味すると同意しますが、[Promises/A + Spec](https ://promisesaplus.com/)は、「解決」という用語を「保留」状態から「完了」または「拒否」に変更することを意味します。新しい言葉を導入するよりも、むしろその用語に固執したいと思います。 [約束/ A +約束手続き](https://promisesaplus.com/#point-45)を参照してください。 – georgeawg

0
firstPromise().catch().secondPromise().catch().then(//what you want) 

上記の約束のチェーンがこれを達成することができます。最終thenは、すべてのシナリオで呼び出されます。 catchは約束の拒否を伝播するでしょう。

+0

私は正しく質問しなかったようです。 'finally'は、両方の約束が遂行されたとき(拒絶または解決)にのみ呼び出されるべきです。私はすべての約束が完了するのを待っていたい。だからこれは正しく動作しません。 – Hemant

+0

は答えを – raj

1

Promise.all(iterable)は、あなたが探していることを行います。ただし、Internet Exploerはこの方法をサポートしていないため、ブラウザの互換性を確認してください。ドキュメントから:

Promise.all(反復可能)メソッドは、反復可能な引数での約束のすべてが解決、または拒否する最初に渡さ約束の理由で を拒否してきたとき 解決する約束を返します。故障ブロックが成功ブロックと同じであっても

Promise.all([firstPromise, secondPromise]).then(values => { 
    finallyHandler(); 
}, reason => { 
    finallyHandler(); 
}); 

、成功ブロックは一度だけ、すべての約束を実行します(障害時の動作で)、それは次のようになりますあなたのコードの例を使用して

正常に完了し、障害ブロックは最初の障害が発生したときに1回(1回のみ)実行されます。

参考:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

関連する問題