web-dev-qa-db-ja.com

RxJS ObservablesでのPromise.allの動作?

Angular 1.xでは、複数のhttp要求を作成し、すべての応答で何かをする必要がある場合があります。配列にすべてのプロミスをスローし、Promise.all(promises).then(function (results) {...})を呼び出します。

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

67
Corey Ogburn

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

少し範囲外ですが、それが役立つ場合は、Promiseのチェーンの問題で、単純なflatMap:Cfを使用できます。 RxJS Promise Composition(データを渡す)

66
user3743222

forkJoinも正常に機能しますが、 combineLatest をお勧めします。これは、オブザーバブルの最後の値を取得することを心配する必要がないためです。この方法では、それらのいずれかが新しい値を発行するたびに更新することができます(たとえば、間隔または何かでフェッチします)。

12
kakigoori

On reactivex.ioforkJoinは実際に Zip を指し、これは私のために仕事をしました:

let subscription = Observable.Zip(obs1, obs2, ...).subscribe(...);
11
Arnaud P

RxJs v6を使用して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!' ]
6
arcseldon