RxJS ObservablesでのPromise.allの動作?


87

Angular 1.xでは、複数のhttpリクエストを行い、すべての応答で何かを行う必要がある場合がありました。すべてのpromiseを配列に入れて、を呼び出しますPromise.all(promises).then(function (results) {...})

Angular 2のベストプラクティスはObservablehttpリクエストの約束の代わりにRxJSを使用することを示しているようです。httpリクエストから作成された2つ以上の異なるObservableがある場合、同等のものはありPromise.all()ますか?

回答:


77

エミュレートするためのより簡単な代替方法Promise.allは、forkJoin演算子を使用することです(すべてのオブザーバブルを並行して開始し、最後の要素を結合します)。

少し範囲外ですが、それが役立つ場合は、約束の連鎖に関して、単純なflatMap:Cfを使用できます。RxJS Promiseコンポジション(データの受け渡し)


1
2つの呼び出しがある場合、1つのリターンプロミスと別のリターンが観察可能である場合、ユーザーはフォークジョインできますか?またはpromise.all()?または誰も、私は2つの関数がpromiseまたはobservableのいずれかで同じタイプを返すようにする必要がありますか?
Joe Sleiman 2017年

1
パラメータとして渡されたオブザーバブルが値を出力しない場合、forkJoinは機能しません。Observableが無効で、forkJoin機能を使用したいのですが、機能していません
Goga Koreli 2018年

18

RxJsv6を使用して2019年5月に更新

他の回答が有用であることがわかり、zip使用法についてArnaudが提供した回答の例を提供したいと考えました。

これは、Promise.allとrxjsの間の同等性を示すスニペットですzip(rxjs6では、演算子としてではなく「rxjs」を使用してzipがインポートされる方法にも注意してください)。

import { zip } from "rxjs";

const the_weather = new Promise(resolve => {
  setTimeout(() => {
    resolve({ temp: 29, conditions: "Sunny with Clouds" });
  }, 2000);
});

const the_tweets = new Promise(resolve => {
  setTimeout(() => {
    resolve(["I like cake", "BBQ is good too!"]);
  }, 500);
});

// Using RxJs
let source$ = zip(the_weather, the_tweets);
source$.subscribe(([weatherInfo, tweetInfo]) =>
  console.log(weatherInfo, tweetInfo)
);

// Using ES6 Promises
Promise.all([the_weather, the_tweets]).then(responses => {
  const [weatherInfo, tweetInfo] = responses;
  console.log(weatherInfo, tweetInfo);
});

両方からの出力は同じです。上記を実行すると、次のようになります。

{ temp: 29, conditions: 'Sunny with Clouds' } [ 'I like cake', 'BBQ is good too!' ]
{ temp: 29, conditions: 'Sunny with Clouds' } [ 'I like cake', 'BBQ is good too!' ]

13

forkJoinも正常に機能しますが、observableの最後の値を取ることを心配する必要がないため、combineLatestをお勧めします。このようにして、それらのいずれかが新しい値を発行するたびに更新を取得できます(たとえば、間隔などでフェッチします)。


1
これは私の現在のニーズを満たしていませんが、私は間違いなくすぐにそれを使用します。
Corey Ogburn 2016

4
これはPromise.all()と同じ動作を実現しませんが、Promise.any()に似ています
Purrell 2016

2つの呼び出しがある場合、1つのリターンプロミスと別のリターンが観察可能である場合、ユーザーはフォークジョインできますか?またはpromise.all()?または誰も、私は2つの関数がpromiseまたはobservableのいずれかで同じタイプを返すようにする必要がありますか?
Joe Sleiman 2017年

1
@JoeSleimanは少し遅れますが、あなたはあなたの側を選ぶことができます:Observable.fromPromise()Observable.zip()、またはObserable.toPromise()とPromise.all()
Arnaud P

11

オンreactivex.io forkJoinに実際にポイントジップ私のために仕事をしました、:

let subscription = Observable.zip(obs1, obs2, ...).subscribe(...);

「つまり、forkJoinは複数回発行されず、その後完了します。渡されたオブザーバブルのライフサイクルの終了時だけでなく、その全体にわたって結合された値を発行する必要がある場合は、代わりにcombineLatestまたはzipを試してください。」rxjs-dev.firebaseapp.com/api/index/function/forkJoin
ジェフリー・ニコルソンカレ

2
forkJoinはすべてのオブザーバブルが終了するのを待ちますが、zipはすべての入力が最初の値を出力するときに配列を出力します。zipは何度も放出される可能性があります。http呼び出しがある場合、違いはありません。
hgoebl

そうです、私は今微妙になりました、乾杯。言語セクションが拡張されていることに気づいていませんでした-_-
Arnaud P
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.