如何访问publishReplay().refCount()内部ReplaySubject及判断是否有观察者?
解决RxJS5中判断publishReplay+refCount的Observable是否有观察者的问题
嘿,这个问题我之前也碰到过,RxJS5移除了Subject的hasObservers()方法,而且publishReplay(1).refCount()生成的Observable内部的ReplaySubject是作为私有属性存在的,直接访问会有兼容性风险。下面给你两个实用的解决方案:
方案一:自定义带观察者跟踪的Observable(推荐)
我们可以自己封装一个Observable,手动跟踪观察者的数量,同时保留publishReplay(1)和refCount()的特性,还能添加自己的hasObservers()方法。代码示例如下:
import { Observable, ReplaySubject } from 'rxjs'; function createReplayRefCountObservable(source$) { const replaySubject = new ReplaySubject(1); let observerCount = 0; // 先创建可连接的Observable const connectable$ = source$.multicast(replaySubject); // 应用refCount自动管理连接 const refCounted$ = connectable$.refCount(); // 包装原始Observable,跟踪观察者数量 const obs$ = Observable.create(observer => { observerCount++; // 订阅到refCounted的Observable const subscription = refCounted$.subscribe(observer); // 取消订阅时减少计数 return () => { subscription.unsubscribe(); observerCount--; }; }); // 添加hasObservers方法 obs$.hasObservers = () => observerCount > 0; return obs$; } // 使用示例 const yourSource$ = Observable.create(observer => { console.log('源Observable开始执行'); observer.next('test data'); }); const obs$ = createReplayRefCountObservable(yourSource$); // 测试hasObservers console.log(obs$.hasObservers()); // 输出false const sub1 = obs$.subscribe(); console.log(obs$.hasObservers()); // 输出true sub1.unsubscribe(); console.log(obs$.hasObservers()); // 输出false
这个方案不依赖RxJS的内部私有属性,兼容性更好,适合生产环境使用。
方案二:直接访问内部私有Subject(不推荐)
如果你只是在调试或者临时场景下使用,可以直接访问publishReplay()返回的ConnectableObservable的内部_subject属性(RxJS5中是这个命名),但要注意私有属性随时可能在版本更新中被修改或移除,风险很高:
import { Observable } from 'rxjs'; const source$ = Observable.create(...); // 先创建ConnectableObservable,不要直接链式调用refCount const connectable$ = source$.publishReplay(1); const obs$ = connectable$.refCount(); // 获取内部的ReplaySubject const replaySubject = connectable$._subject; // 判断是否有观察者 const hasObservers = replaySubject.observers.length > 0;
这个方法简单但不稳定,不建议在正式项目中使用。
内容的提问来源于stack exchange,提问作者jeanpaul62
相关产品推荐
相关产品推荐

