Rx Observableで「待機」するにはどうすればよいですか?


106

オブザーバブルで待つことができるようにしたい、例えば

const source = Rx.Observable.create(/* ... */)
//...
await source;

素朴な試みの結果、待機はすぐに解決され、実行はブロックされません

編集:私の完全な使用目的の疑似コードは次のとおりです:

if (condition) {
  await observable;
}
// a bunch of other code

他のコードを別の別の関数に移動してサブスクライブコールバックに渡すことができることを理解していますが、それを回避できることを願っています。


(ソースを待機したい)残りのコードを.subscribe()メソッド呼び出しに移動できませんか?
StriplingWarrior 2015

回答:


132

あなたは約束をする必要がありawaitます。オブザーバブルの次のイベントを約束に変換して、それを待ちます。

if (condition) {
  await observable.first().toPromise();
}

注を編集:この回答は元々.take(1)を使用していましたが、値が到達する前にストリームが終了した場合にPromiseが解決しないという問題を回避する.first()を使用するように変更されました。


3
take(1)の代わりに使用できますawait observable.first().toPromise();か?
apricity 2016年

14
@apricity完了時に値がなかった場合first()、拒否さ take(1)れ、保留中の約束になります。
Estus Flask 2016

6
@apricity @AgentME実際には、このような場合take(1)も使用しないfirst()でください。あなたは正確に1つのイベントが起こることを期待しているのでsingle()、1つ以上ある場合に例外をスローするイベントを使用する必要がありますが、何もない場合は例外をスローしません。1つ以上ある場合、コード/データモデルなどに問題がある可能性があります。singleを使用しない場合は、最初の項目が勝手に選択され、それ以上はないという警告なしに戻ります。常に同じ順序を維持するには、上流のデータソースの述語に注意する必要があります。
ntziolis 2017年

3
インポートを忘れないでください:import 'rxjs/add/operator/first';
ステファニー

7
toPromise()が廃止されたので、これをどのように行う必要がありますか?
Jus10、18年

26

それはおそらくする必要があります

await observable.first().toPromise();

以前のコメントで述べたように、空の完了オブザーバブルがある場合、take(1)first()オペレーターの間にはかなりの違いがあります。

Observable.empty().first().toPromise()EmptyError本当に価値がなかったので、それに応じて処理することができ、それで拒否されます。

そしてObservable.empty().take(1).toPromise()undefined価値のある解決をもたらすでしょう。


実際take(1)、保留中の約束得られません。それはで解決された約束をもたらすでしょうundefined
Johan t Hart

お気づきありがとうございます。投稿が異なった理由がわかりません。おそらく、ある時点で動作が変更されました。
Estus Flask


4

toPromiseが非推奨の場合は使用できます.pipe(take(1)).toPromiseが、ここでわかるように、非推奨ではありません。

そのため、次のようにtoPromise(RxJs 6)を使用してください。

//return basic observable
const sample = val => Rx.Observable.of(val).delay(5000);
//convert basic observable to promise
const example = sample('First Example')
  .toPromise()
  //output: 'First Example'
  .then(result => {
    console.log('From Promise:', result);
  });

非同期/待機の例:

//return basic observable
const sample = val => Rx.Observable.of(val).delay(5000);
//convert basic observable to promise
const example = await sample('First Example').toPromise()
// output: 'First Example'
console.log('From Promise:', result);

詳細はこちら

そして、この誤った主張を削除してくださいtoPromise

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.