1. ホーム
  2. javascript

[解決済み] RxJSで2つのobservableを'待つ'方法

2022-10-27 09:05:14

質問

私のアプリでは、次のようなものがあります。

this._personService.getName(id)
      .concat(this._documentService.getDocument())
      .subscribe((response) => {
                  console.log(response)
                  this.showForm()
       });

 //Output: 
 // [getnameResult]
 // [getDocumentResult]

 // I want:
 // [getnameResult][getDocumentResult]

それから、2つの分離された結果が得られます。 _personService で、次に _documentService . どうすれば、両方の結果を待ってから this.showForm() を呼び出してから、それぞれの結果を操作するにはどうしたらよいでしょうか。

どのように解決するのですか?

最終更新日:2021年6月。

RxJS v7: combineLatestWith。

reactiveXより ドキュメント :

入力のObservableが値を出力するたびに、すべての入力からの最新の値を用いて計算式を計算し、その計算式の出力を出力します。

// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
name$.pipe(
        combineLatestWith((name, document) => {name, document})
      )
      .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })

(非推奨) RxJS v6 combineLatest()

reactiveXより ドキュメント :

入力のObservableが値を出力するたびに、すべての入力からの最新の値を用いて計算式を計算し、その計算式の出力を出力します。

(更新日: 2021年2月) :

// Deprecated (RxJS v6)
// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
name$.combineLatest(document$, (name, document) => {name, document})
    .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })

(代替構文) : combineLatest(観測値)

// Deprecated (RxJS v6)
// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
combineLatest(name$, document$, (name, document) => ({name, document}))
    .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })


zipとcombineLatestの比較

(更新: 2018年10月) 以前、私が提案した zip メソッドの使用を提案しました。しかし、いくつかの使用例では combineLatest よりもいくつかの利点があります。 zip . ですから、その違いを理解することが重要です。

CombineLatest は、observableから最新のemitted値を放出します。一方 zip メソッドは シーケンス の順番になります。

例えば、観測点#1がその 3番目 という項目があり、観測器#2がその 5番目 という項目があります。その結果 zip メソッドを使った結果は 3番目 の両方の値が出力されます。 observables .

この場合 combineLatest 5番目 であり 3位 .の方がより自然に感じられます。


Observable.zip(観測値)

(元の回答:2017年7月) Observable.zipのメソッドについて説明します。 reactiveXドキュメント :

<ブロッククオート

複数のObservableを組み合わせて、入力のObservableの値から順番に計算された値を持つObservableを作成します。

// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
Observable
    .zip(name$, document$, (name: string, document: string) => ({name, document}))
    .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })


補足説明 (両方の方式に適用されます)

最後のパラメータで、関数を提供したところ。 (name: string, document: string) => ({name, document}) は省略可能です。省略することもできますし、より複雑な処理を行うこともできます。

latestパラメータが関数の場合、この関数は入力値から生成値を計算するために使用されます。そうでない場合は、入力値の配列が返されます。

つまり、最後の部分をスキップすると、配列が得られるということですね。

// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
Observable
    .zip(name$, document$)
    .subscribe(pair => {
           this.name = pair['0'];
           this.document = pair['1'];
           this.showForm();
       })