我有一个功能代码片段,它使用 Angular 服务创建 Observable 管道。该代码使用 mergeMap、filter、map 和 shareReplay(1) 运算符来处理用户身份验证并从用户配置文件中检索加入状态。该管道旨在重复使用,以有效观察入职状态的变化。
当我将此逻辑封装在函数中并返回生成的 Observable 或将其分配给类属性时,我观察到不同的行为。当我从函数返回 Observable 时,管道内的整个链在每个订阅上执行。另一方面,如果我将 Observable 分配给类属性,则 shareReplay(1) 运算符将按预期工作,并且整个链仅执行一次。
我对这种差异感到困惑,并怀疑这可能与新实例的创建有关。你能帮我理解为什么从函数返回 Observable 和将其分配给类属性之间的行为不同吗?如何在这两种情况下使用 shareReplay(1) 运算符实现一致的行为?
user$ = user(this.auth).pipe(shareReplay(1));
getStatus(): Observable<> {
return this.angularService.user$.pipe(
mergeMap(user => {
console.log('Onboarding merge map');
return this.angularService.getUserProfile(user?.uid || "").pipe(
filter(({ profile, user }) => {
console.log('Filter: ', profile['onboarding'])
return profile && profile['onboarding'];
}),
map(d => d.profile['onboarding'])
)
}),
shareReplay(1)
);
}
user$ = user(this.auth).pipe(shareReplay(1));
readonly onboardingStatus$: Observable<> = this.angularService.user$.pipe(
mergeMap(user => {
console.log('Onboarding merge map');
return this.angularService.getUserProfile(user?.uid || "").pipe(
filter(({ profile, user }) => {
console.log('Filter: ', profile['onboarding'])
return profile && profile['onboarding'];
}),
map(d => d.profile['onboarding'])
)
}),
shareReplay(1)
);
如果你有这样的功能
function retObs() {
return of('something')
}
任何时候你调用这样的函数,你都会得到一个新的 Observable 实例。因此,如果你有这样的东西
function retObs() {
return of('something'),pipe(share(1))
}
const sub1 = retObs().subscribe()
const sub2 = retObs().subscribe()
每个订阅订阅不同的 Observable 链,因此
shareReplay(1)
对这些订阅没有任何影响。
相反,如果您将
retObs()
返回的 Observable 实例保存在变量中,则该变量持有的 Observable 的所有订阅共享同一个 Observable 链,因此您会看到您所期望的 shareReplay(1)
的效果。
const var = retObs()
const sub1 = var.subscribe()
const sub2 = var.subscribe()
这个stackblitz展示了这个概念的实际应用。