繁体   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