web-dev-qa-db-ja.com

RXJSパイプ内の複数のオブザーバブルを組み合わせる

特定の量のIDを返すAPI呼び出しがあります。これらの各IDは、新しいAPI呼び出しを行うために使用されます。これらのAPI呼び出しの結果は、単一のオブジェクトに結合する必要があります。

最初に、最初のapi呼び出しの.pipe(map)オペレーター内でループを使用しました。このループでは、2番目のapi呼び出しを実行しました。これらの各呼び出しの.pipe(map)演算子では、angularコンポーネントの変数を編集します。

これはあまりきれいではありませんでした。実際、これがスレッドセーフかどうか疑問に思いました。私はJavaScriptがシングルスレッドであることを知っていますが、複数の非同期プロセスが同じグローバル変数を使用するのは安全ではないようです。

その後、2番目のapi呼び出しで返されたオブザーバブルをapiCall1で返されたIDをループすることで配列に格納し、forkJoinを使用して各結果をサブスクライブして処理しました(例を参照)。

これはあまりきれいではありませんが、パイプで使用できる演算子があるかどうか疑問に思っていましたか?

(pseudocode)の代わりに:

  .pipe(
      map(ids=> {

        let observables = []
        for (const id of ids) {
         observables.Push(this.service.getSomeStuff(id));
        }

        forkJoin(...observables).subscribe(dataArray) => {
          for (data of dataArray) {
            //Do something
          }
        });

      }),
      takeWhile(() => this.componentActive),
      catchError(error => {
        console.log(error);
        return throwError(error);
      })
    )
    .subscribe();

これを次のようにする演算子はありますか?

  .pipe(
      map(ids=> {

        let observables = []
        for (const id of ids) {
         observables.Push(this.service.getSomeStuff(id));
        }

      return observables
      }),
      forkJoin(dataArray => {
          for (data of dataArray) {
            //Do something
          }
        });
      takeWhile(() => this.componentActive),
      catchError(error => {
        console.log(error);
        return throwError(error);
      })
    )
    .subscribe();
5
BartKrul

Forを使用して一度にデータを変更する代わりに、データが受信されたときにそれを実行してみませんか?このようなもの。

source$.pipe(
  mergeMap(ids => from(ids)),
  mergeMap(id => this.service.getSomeStuff(id)),
  tap(data => //do someting with the data);
  takeWhile(() => this.componentActive),
  catchError(error => {
    console.log(error);
    return throwError(error);
  }),
  toArray(), --> this create the array of all the values received.
)
.subscribe(data => //returns array of modified data);
0
emkay