【问题标题】:RxJS: Share() an Observable & Emit Last Value to each new subscriberRxJS: Share() 一个 Observable & Emit Last Value 给每个新订阅者
【发布时间】:2017-06-30 09:34:31
【问题描述】:

我正在使用 .share() 在服务的所有订阅者之间共享一个 Observable:

@Injectable()
export class ChannelsService {
    private store: IChannel[] = [];
    private _own: BehaviorSubject<IChannel[]> = new BehaviorSubject([]);
    readonly own: Observable<IChannel[]> = this._own.asObservable().share();
    ...(the rest of the service basically makes CRUD http request and then calls this._own.next(result) to emit the result to all subscribers)
}

问题: 只有对 Observable (ChannelsService.own.subscribe(...)) 的第一个订阅正在获取初始数据,其余订阅将“null”作为第一个订阅的值。对 this._own.next(result) 的下一次调用将正确地将其值发送给所有订阅者。

知道如何在多个订阅者之间共享()一个 Observable 并获取为所有订阅者发出的最后一个值吗? (我试过 .share().last() 但没办法...)。

谢谢!

【问题讨论】:

    标签: angular rxjs observable angular2-services


    【解决方案1】:

    你可能想要shareReplay()(自 RxJS 5.4.0 起)或 RxJS publishReplay().refCount()。

    例如:

    this._own.asObservable()
      .publishReplay(1)
      .refCount()
      .take(1);
    

    【讨论】:

    • 感谢您的回答和详细的链接,它有效!我还推荐阅读这篇文章:blog.thoughtram.io/angular/2016/06/16/… 它帮助我理解了潜在的问题:冷和热 observables 之间的区别。它推荐 publishLast().refCount(),据我所知,它的工作方式相同:它在所有订阅者之间共享相同且唯一的订阅,并在订阅时发出最后一个值。
    【解决方案2】:

    一些小的改进:

    @Injectable()
    export class ChannelsService {
        private store: IChannel[] = [];
        private _own: BehaviorSubject<IChannel[]> = new BehaviorSubject([]);
        get own(){
          this._own.asObservable();
        }
    }
    

    现在您可以在组件中执行以下操作:

    channels$: Observable<IChannel[]> = this.service.own;
    

    如果您手动订阅它,不要忘记取消订阅它

    【讨论】:

    • 感谢您的评论@Jota.Toledo。也许您的选择更优雅,但是这样我也可以从组件中调用 this.channelsService.own ...
    • 去掉共享操作符没有效果?
    【解决方案3】:

    您的结果是使用 share 而没有初始化值的预期结果。 Explanation

    如前所述.. 您有一些快捷方式可以帮助您处理此用例。只是一个简单的添加:将“null”作为初始值并由那些不是的人过滤。

    const subject = new Rx.Subject();
    
    const behaviorWithoutShortcut = subject
      .multicast(new Rx.BehaviorSubject(null))
      .refCount()
      .filter(function (x) { return x !== null; });
    
    const behaviorWithShortcut = subject
      .publishBehavior(null)
      .refCount()
      .filter(function (x) { return x !== null; });
    

    我刚刚做了一个例子jsbin example

    【讨论】:

      猜你喜欢
      • 2019-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多