在将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,我需要使用它。
答案 0 :(得分:3)
您将无法完全完成async
/ await
的操作,因为您仍然必须具有.subscribe
回调,并且可能有多个属性被发射。您应该从不嵌套.subscribe
调用。通常,您将使用更高阶的Observable运算符,例如mergeMap
,或将多个Observable的发射同步在一起的Observable创建者,例如combineLatest
:
combineLatest(AsyncFooData(), AsyncBarData()).subscribe([fooData, barData] => {
});
您需要的确切功能取决于您自己的需求以及foo
和bar
发出的方式:
combineLatest
-每次发射任何源时都会发出(注意:直到所有源都发射一次后才开始发射)。zip
-同步排放,例如每个Observable发射一次,然后发射两次,等等。forkJoin
-所有源可观察到的信号完成时发出merge
-发出任何信号源时发出。它不像上面的其他输出那样合并输出。答案 1 :(得分:2)
我认为您正在尝试找到一种“清洁”方式链接多个异步操作的好方法。这就是我要做的:
from()
是因为我假设AsyncFooData
返回了诺言。如果返回Observable,则只需删除from()
。pipe()
以平整的方式链接所需的任意数量的运算符。subscribe()
。注意:编写这些示例是为了共享概念/方法,而无需检查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
并获得fooData
和barData
并做您想做的任何事情。
zip(AsyncFooData(), AsyncBarData()).subscribe([fooData, barData]) => {})
这里以zip
为例。您可以根据需要使用其他运算符,例如combineLatest
。
在这里我不解释zip
和combineLatest
以及其他运算符之间的区别,因为这样做可能会使这个答案混乱。相反,我指向以下资源,并通过图表和示例清楚地说明了这些内容:
(1)Official doc