Typescript RxJs楼梯,当链接可见时

Typescript RxJs楼梯,当链接可见时,typescript,rxjs,Typescript,Rxjs,在使用Promise之前,我在Typescript中使用async/await语法,如下所示 const fooData = await AsyncFooData(); const barData = await AsyncBarData(); ... do something with fooData and barData 如果我用RxJsObservable来做这件事,对我来说就会变成这样 AsyncFooData().subscribe(fooData => { Asyn

在使用Promise之前,我在Typescript中使用async/await语法,如下所示

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

... do something with fooData and barData
如果我用RxJs
Observable
来做这件事,对我来说就会变成这样

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

有没有更好的办法?因为它变得很快,不可读,如果我需要处理更多的异步数据。

你可以
zip
获取
fooData
barData
,然后做任何你想做的事

zip(AsyncFooData(), AsyncBarData()).subscribe([fooData, barData]) => {})
这里以
zip
为例。您可以根据需要使用其他运算符,如
combinelateest

我不想在这里解释
zip
combinelateest
与其他操作符之间的区别,因为这样做可能会弄乱这个答案。取而代之的是,我在下面的参考资料中,用图表和示例清楚地解释了一些事情:

(一)


(2) 您将无法完成使用
异步
/
等待
所做的工作,因为您仍然需要使用
.subscribe
回调,并且可能会发出多个属性。您不应该嵌套
。订阅
调用。通常,您将使用更高阶的可观测操作符,如
mergeMap
,或可观测创建者,将多个可观测的发射同步在一起,如
combinelateest

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

});
您需要的确切功能取决于您自己的需要以及
foo
bar
的发射方式:

  • CombineTest
    -每次任何源发射时发射(注意:直到所有源发射一次后才开始发射)
  • zip
    -同步发射,例如,发射一次,每个可见光发射一次,然后两次,等等
  • forkJoin
    -在所有源观测完成时发出
  • merge
    -在任何源发出时发出。它不像上面的其他输出那样组合输出

还有更多可用的方法:

我认为您正在试图找到一种很好的方法,以“更干净”的方式链接多个异步操作。我就是这么做的:

  • 我使用了
    from()
    ,因为我假设
    AsyncFooData
    返回一个承诺。如果它返回Observable,只需从()中删除
  • 避免多次订阅(通常比我们想象的要少)
  • 使用
    pipe()
  • 所有操作完成后,将调用
    subscribe()
  • 从foo一直为subscribe的下一个函数设置传递结果的样式
  • 样式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
})

谢谢你的提示,我用操作符解决了这个问题。它仍然变得有点长。但是我不再使用
subscribe
,它也不再像楼梯了。谢谢你的提示,我最终按照你的建议使用了操作符。我想这会好一点:)在你的例子中@starcorn,因为你的函数似乎是承诺,所以使用forkJoin。承诺总是完整的。