簡體   English   中英

在 RxJS 中鏈接 Observable

[英]Chaining Observables in RxJS

我正在學習 RxJS 和 Angular 2. 假設我有一個帶有多個異步 function 調用的 promise 鏈,這取決於之前的結果,如下所示:

var promiseChain = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 1000);
}).then((result) => {
  console.log(result);

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(result + 2);
    }, 1000);
  });
}).then((result) => {
  console.log(result);

  return new Promise((resolve, reject) => {
      setTimeout(() => {
      resolve(result + 3);
        }, 1000);
  });
});

promiseChain.then((finalResult) => {
  console.log(finalResult);
});

我嘗試僅使用 RxJS 而不使用承諾來做同樣的事情,結果如下:

var observableChain = Observable.create((observer) => {
  setTimeout(() => {
    observer.next(1);
    observer.complete();
  }, 1000);
}).flatMap((result) => {
  console.log(result);

  return Observable.create((observer) => {
    setTimeout(() => {
      observer.next(result + 2);
      observer.complete()
    }, 1000);
  });
}).flatMap((result) => {
  console.log(result);

  return Observable.create((observer) => {
    setTimeout(() => {
      observer.next(result + 3);
      observer.complete()
    }, 1000);
  });
});

observableChain.subscribe((finalResult) => {
  console.log(finalResult);
});

它產生與 promise 鏈相同的 output。 我的問題是

  1. 我這樣做對嗎? 我可以對上面的代碼進行 RxJS 相關的改進嗎

  2. 我如何讓這個可觀察鏈重復執行? 即在最后添加另一個訂閱只會產生額外的 6,盡管我希望它打印 1、3 和 6。

    observableChain.subscribe((finalResult) => { console.log(finalResult); });

    observableChain.subscribe((finalResult) => { console.log(finalResult); });

    1 3 6 6

關於promise composition vs. Rxjs,因為這是一個常見問題,因此您可以參考一些先前關於SO的問題,其中:

基本上, flatMap相當於Promise.then

對於第二個問題,您是要重放已經發出的值,還是要在到達新值時對其進行處理? 在第一種情況下,請檢查publishReplay運算符。 在第二種情況下,標准訂閱就足夠了。 但是,您可能需要注意感冒。 與熱二分法(具體取決於您的來源)(請參見熱和冷可觀察值:是否存在“熱”和“冷”運算符?以對該概念進行圖解說明)

澄清示例:

pipe 的頂部可以發出 n 個值(這回答了“我如何讓這個可觀察的鏈重復執行”),但隨后的鏈接流發出一個值(因此模仿承諾)。

// Emit three values into the top of this pipe
const topOfPipe = of<string>('chaining', 'some', 'observables');

// If any of the chained observables emit more than 1 value
// then don't use this unless you understand what is going to happen.
const firstObservablePipe = of(1); 
const secondObservablePipe = of(2);
const thirdObservablePipe = of(3);
const fourthObservablePipe = of(4);

const addToPreviousStream = (previous) => map(current => previous + current);
const first = (one) => firstObservablePipe.pipe(addToPreviousStream(one));
const second = (two) => secondObservablePipe.pipe(addToPreviousStream(two));
const third = (three) => thirdObservablePipe.pipe(addToPreviousStream(three));
const fourth = (four) => fourthObservablePipe.pipe(addToPreviousStream(four));

topOfPipe.pipe(
  mergeMap(first),
  mergeMap(second),
  mergeMap(third),
  mergeMap(fourth),
).subscribe(console.log);

// Output: chaining1234 some1234 observables1234

您還可以使用 concatMap 或 switchMap。 它們都有細微的差別。 請參閱 rxjs 文檔以了解。

mergeMap: https://www.learnrxjs.io/learn-rxjs/operators/transformation/mergemap

concatMap: https://www.learnrxjs.io/learn-rxjs/operators/transformation/concatmap

switchMap: https://www.learnrxjs.io/learn-rxjs/operators/transformation/switchmap

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM