Typescript RxJs楼梯,当链接可见时
在使用Promise之前,我在Typescript中使用async/await语法,如下所示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
const fooData = await AsyncFooData();
const barData = await AsyncBarData();
... do something with fooData and barData
如果我用RxJsObservable
来做这件事,对我来说就会变成这样
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。承诺总是完整的。