web-dev-qa-db-ja.com

RXJS演算子を使用して複数の入れ子になった購読を回避するにはどうすればよいですか。

私は角度を使ってファイルの暗号化とアップロードクラスに取り組んでいます。これらの操作の多くは非同期であり、したがって私が書いた方法はRXJS観測値を返します。

_// 1.
private prepareUpload(file): Observable<T>;

// 2.
private encryptData(data, filekey): Observable<T>

// 3.
private uploadEncryptedData(formData, token, range): Observable<T>

// 4.
private completeUpload(updatedFilekey, token): Observable<T>
_

このロジックをPublic upload(file)メソッドにカプセル化したいと思うと、ネストされたサブスクリプションを使用して終了しましたが、それが動作しているが、いくつかの理由でRXJSのアンチパターンであることを知っています。これが簡単なコードの版です。

_public upload(file) {
    const gen = this.indexGenerator(); // generator function

    this.prepareUpload(file).subscribe(values => {
    const [response, filekey, data] = values;

    this.encryptData(data, filekey).subscribe(encryptedDataContainer => {
      const formData = this.prepareEncDataUpload(encryptedDataContainer.data, file.name)
      const range = this.getRange(file.size, gen.next().value);

      this.uploadEncryptedData(formData, response.token, range).subscribe(() => {
        if (range.isFinalPart) {
            this.completeUpload(encryptedDataContainer.updatedFilekey, response.token).subscribe(console.log);
        }
      });

    });

  });

}
_

私はいくつかのRXJS演算子の組み合わせを使用してこのコードを清掃できませんでした。私の目標は、入れ子になった購読を避け、代わりにワークフローが完了したときにPublic upload()メソッドから単一の観察可能なものを返します。

ありがとう!

9
Benny1158

MergeMap RXJS演算子を使用してそれらの観察者をマージすることができ、ネストされた購読を取り除くことができます。

1つのキャッチがあるが、Mergemapは一度に複数のアクティブな内部サブスクリプションを維持すると、長期間の内部サブスクリプションを介してメモリリークを作成することが可能であることに注意してください。

参考のために: https://www.learnrxjs.io/operators/transformation/mergemap.html

0
Sumit Vekariya

私はあなたの観察者を連鎖させるだろうと思います、あなたはそれをFlatMapのためにそれをすることができます(Mergemapのためのエイリアス)--- https://stackoverflow.com/a/37777382/9176461RXJS Promise Conditods (データを渡す)

私のコメントのようにメントーインされている、次のようなものは仕事をするべきです(疑似コード):

public upload(file) {
    const gen = this.indexGenerator(); // generator function

    return Rx.Observable.just(file).pipe(
         mergeMap(this.prepareUpload),
         mergeMap(this.encryptData),
         mergeMap(this.prepareEncDataUpload),
         mergeMap(this.prepareEncDataUpload),
         .... )
}
 _
0
J. Knabenschuh