And*_*hov 2 javascript class rxjs firebase angular
我有一个功能代码片段,它使用 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)
);
}
Run Code Online (Sandbox Code Playgroud)
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)
);
Run Code Online (Sandbox Code Playgroud)
更新:添加可能导致在返回时调用“new”的函数,如果将其更改为变量可能会改变原始函数的行为,则会给出更新:
getUserProfile(uid: string): Observable<{ profile: DocumentData, user: User }> {
return documentSnapshot(doc(this.firestore, "users", uid)).pipe(
tap((val) => console.log(`userProfile document snapshot executed`, val)),
mergeMap((document) => (of({ profile: document.data(), user } as any))),
shareReplay(1)
);
}
Run Code Online (Sandbox Code Playgroud)
如果你有这样的功能
function retObs() {
return of('something')
}
Run Code Online (Sandbox Code Playgroud)
任何时候你调用这样的函数,你都会得到一个新的 Observable 实例。因此,如果你有这样的东西
function retObs() {
return of('something'),pipe(share(1))
}
const sub1 = retObs().subscribe()
const sub2 = retObs().subscribe()
Run Code Online (Sandbox Code Playgroud)
每个订阅都订阅不同的 Observable 链,因此shareReplay(1)对这些订阅没有任何影响。
相反,如果将返回的 Observable 实例保存在变量中,则该变量持有的 Observable 的所有订阅共享同一个 Observable 链,因此您会看到预期retObs()的效果。shareReplay(1)
const var = retObs()
const sub1 = var.subscribe()
const sub2 = var.subscribe()
Run Code Online (Sandbox Code Playgroud)
这个stackblitz展示了这个概念的实际应用。
| 归档时间: |
|
| 查看次数: |
87 次 |
| 最近记录: |