2017-06-30 40 views
0

我使用.share()來共享可觀察到的所有訂戶到服務之中:RxJS:分享()可觀察到的和的Emit最後一個值到每個新用戶

@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()但沒辦法......)。

謝謝!

回答

1

您可能需要shareReplay()(自RxJS 5.4.0開始)或publishReplay().refCount()開始RxJS < 5.4.0。

例如:

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

謝謝你的回答和詳細的鏈接,它的工作! 我也會推薦閱讀這篇文章:https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html#card_1501173301527_7527 它幫助我瞭解潛在的問題:冷熱觀察的差異。它推薦publishLast()。refCount(),根據我所見,它的工作方式相同:它在所有訂閱者之間共享相同且唯一的訂閱,併發布訂閱時的最後一個值。 – aleixsuau

0

一些小的改進:

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

現在你可以做你的組件如下:

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

而且不要忘記從中退訂如果u手動訂閱它

+0

感謝。也許你的選擇更優雅,但這樣我可以從組件調用this.channelsService.own ... – aleixsuau

+0

去除共享運算符沒有影響? –

0

你的結果預期的使用份額沒有初始值。 Explanation

正如之前所評論的那樣..您有快捷方式可以幫助您處理此用例。只是一個簡單的補充:給予「空」作爲初始值,並由那些沒有的人過濾。

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; }); 

我只是做了一個例子您的評論@ Jota.Toledo jsbin example