Zac*_*ier 6 subject observable rxjs angular-observable rxjs6
我发现自己对尝试设置一个非常简单的 rxjs 订阅流程感到困惑。将多个不相关的订阅嵌套到另一个订阅中。
我在一个有角度的应用程序中,在进行其他订阅之前我需要填写一个主题。
这将是我想要实现的嵌套版本。
subject0.subscribe(a => {
this.a = a;
subject1.subscribe(x => {
// Do some stuff that require this.a to exists
});
subject2.subscribe(y => {
// Do some stuff that require this.a to exists
});
});
Run Code Online (Sandbox Code Playgroud)
我知道嵌套订阅不是一个好的做法,我尝试使用flatMaporconcatMap但并没有真正了解如何实现这一点。
将每个 Observable 的数据流分开总是一个好主意,这样您以后就可以轻松地将它们组合起来。
const first$ = this.http.get('one').pipe(
shareReplay(1)
)
Run Code Online (Sandbox Code Playgroud)
用于shareReplay使 Observable 变得热门,这样它就不会http.get('one')针对每个订阅进行调用。
const second$ = this.first$.pipe(
flatMap(firstCallResult => this.http.post('second', firstCallResult))
);
const third$ = this.first$.pipe(
flatMap(firstCallResult => this.http.post('third', firstCallResult))
);
Run Code Online (Sandbox Code Playgroud)
之后,您可以订阅您需要的 Observables:
second$.subscribe(()=>{}) // in this case two requests will be sent - the first one (if there were no subscribes before) and the second one
third$.subscribe(() => {}) // only one request is sent - the first$ already has the response cached
Run Code Online (Sandbox Code Playgroud)
如果您不想将first$的值存储在任何地方,只需将其转换为:
this.http.get('one').pipe(
flatMap(firstCallResult => combineLatest([
this.http.post('two', firstCallResult),
this.http.post('three', firstCallResult)
])
).subscribe(([secondCallResult, thirdCallResult]) => {})
Run Code Online (Sandbox Code Playgroud)
您也可以使用BehaviorSubject它来存储其中的值:
const behaviorSubject = new BehaviorSubject<string>(null); // using BehaviorSubject does not require you to subscribe to it (because it's a hot Observable)
const first$ = behaviorSubject.pipe(
filter(Boolean), // to avoid emitting null at the beginning
flatMap(subjectValue => this.http.get('one?' + subjectValue))
)
const second$ = first$.pipe(
flatMap(firstRes => this.http.post('two', firstRes))
)
const third$ = first$.pipe(
flatMap(()=>{...})
)
behaviorSubject.next('1') // second$ and third$ will emit new values
behaviorSubject.next('2') // second$ and third$ will emit the updated values again
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10395 次 |
| 最近记录: |