【问题标题】:shareReplay: can I reset or set the buffer size to 0 so that new subriptions have to wait for a new emitshareReplay:我可以将缓冲区大小重置或设置为 0,以便新的 subriptions 必须等待新的发射
【发布时间】:2026-01-31 19:35:01
【问题描述】:

我有以下可观察的:

this.roles$ = auth.User$
            .pipe(tap((val: JwtUser|null) => this.logger.debug('Session updated, updating permissions %o', val)))
            .pipe(switchMap(this.getRoles.bind(this)))
            .pipe(shareReplay({refCount: true, bufferSize: 1}));

getRoles() 方法在 User$ 每次发出时执行一个 HTTP 请求。最后获取的值将重播给所有新订阅。但是,当 User$ 发出时,我不希望订阅获得最后一个值。相反,我希望他们等待新获取的。我想我可以通过在 User$ 发出时重置/清除缓冲区来实现这一点,但我不知道如何做到这一点。有没有我可以尝试的其他方法或实现这一目标的方法?

谢谢!

【问题讨论】:

  • 您可以将skip(1) 用于不需要缓存值的订阅。但是,如果缓存为空,这可能会跳过第一次发射。
  • 我有点困惑:'User$ 发出,但是,我不希望订阅获得最后一个值。相反,我希望他们等待新取的';不是'最后一个值'==='新取一个'吗?据我所知,然后源(User$)发出,使用中的ReplaySubject 会将值传递给其注册订阅者(现有订阅)。
  • 问题是当 User$ 已经发出新值但 getRoles 尚未返回时发生新订阅。此订阅将获得过时的角色,这是不行的。

标签: angular typescript rxjs observable


【解决方案1】:

如果我理解正确,您实际上喜欢 0 的缓冲区大小。但是,shareReplay(0) 会像 shareReplay(1) 一样发出源的最后一个值(请参阅 thisshareReplay 的解释)。您可以改用share 和虚拟订阅者:

this.roles$ = auth.User$
            .pipe(tap((val: JwtUser|null) => this.logger.debug('Session updated, updating permissions %o', val)))
            .pipe(switchMap(this.getRoles.bind(this)))
            .pipe(share());
// keep `refCount` above 0 using a dummy subscription
this.roles$.subscribe(() => {});

如果这符合您的要求,请通过评论告诉我。

【讨论】:

  • 我确实以类似的方式规避了这个问题。感谢您的回复!
  • @SanderDechamps 欢迎您。请考虑接受我的回答;-)
最近更新 更多