链接可观察时的RxJs楼梯

时间:2018-06-27 14:53:42

标签: typescript rxjs

在将Typem中的async / await语法用于Promise之前,如下所示

const fooData = await AsyncFooData();
const barData = await AsyncBarData();

... do something with fooData and barData

如果我用RxJs Observable<T>做到这一点,对我来说就像这样

AsyncFooData().subscribe(fooData => {
   AsyncBarData().subscribe(barData => {
      ... do something with fooData and barData
   })
})

有更好的方法吗?因为它很快变得不可读,所以如果要使用更多的AsyncData,我需要使用它。

3 个答案:

答案 0 :(得分:3)

您将无法完全完成async / await的操作,因为您仍然必须具有.subscribe回调,并且可能有多个属性被发射。您应该从不嵌套.subscribe调用。通常,您将使用更高阶的Observable运算符,例如mergeMap,或将多个Observable的发射同步在一起的Observable创建者,例如combineLatest

combineLatest(AsyncFooData(), AsyncBarData()).subscribe([fooData, barData] => {

});

您需要的确切功能取决于您自己的需求以及foobar发出的方式:

  • combineLatest-每次发射任何源时都会发出(注意:直到所有源都发射一次后才开始发射)。
  • zip-同步排放,例如每个Observable发射一次,然后发射两次,等等。
  • forkJoin-所有源可观察到的信号完成时发出
  • merge-发出任何信号源时发出。它不像上面的其他输出那样合并输出。

还有更多可用内容:https://www.learnrxjs.io/operators/combination/

答案 1 :(得分:2)

我认为您正在尝试找到一种“清洁”方式链接多个异步操作的好方法。这就是我要做的:

  • 我使用from()是因为我假设AsyncFooData返回了诺言。如果返回Observable,则只需删除from()
  • 避免多次订阅(通常不如我们想象的那样频繁)。
  • 使用pipe()以平整的方式链接所需的任意数量的运算符。
  • 完成所有操作后,将调用
  • subscribe()
  • 样式foo的结果一直传递到订阅的下一个函数。
  • 样式B仅适用于上一个异步操作的结果。

注意:编写这些示例是为了共享概念/方法,而无需检查IDE语法。如果出现语法错误,该概念应该可以奏效,但要道歉。

// A: if you need both foo and bar
from(AsyncFooData()).pipe(
  concatMap(foo => AsyncBarData().pipe(
    map(bar => ({foo, bar})
  )),
  tap(val => console.log(val), // chain more operators here...
).subscribe(({foo, bar}) => {
  // do stuff with foo and bar
})

// B: if foo is only used to get bar (i.e. no need to pass it along)
from(AsyncFooData()).pipe(
  concatMap(foo => AsyncBarData(foo)), // assume foo is only used to get bar
  tap(val => console.log(val), // chain more operators here...
).subscribe(bar => {
  // do stuff with bar
})

答案 2 :(得分:1)

您可以zip并获得fooDatabarData并做您想做的任何事情。

zip(AsyncFooData(), AsyncBarData()).subscribe([fooData, barData]) => {})

这里以zip为例。您可以根据需要使用其他运算符,例如combineLatest

在这里我不解释zipcombineLatest以及其他运算符之间的区别,因为这样做可能会使这个答案混乱。相反,我指向以下资源,并通过图表和示例清楚地说明了这些内容:

(1)Official doc

(2)Marble diagrams