如何检测MobX Observable是否存在订阅者?求订阅触发事件方案
检测MobX Observable订阅者的两种优雅方案
刚好我之前也遇到过类似的需求,MobX其实提供了现成的API来处理这个场景,不用自己造轮子,给你两种方案参考:
方案一:主动检查订阅者数量
如果你想在调用fetchData时手动判断是否有订阅者,可以用MobX提供的getObserverCount函数,它能直接返回某个Observable的订阅者数量。
实现代码
import { observable, autorun, getObserverCount } from "mobx"; class SomeStore { @observable responseData; fetchData(){ // 如果没有任何订阅者,直接返回 if (getObserverCount(this.responseData) === 0) return; fetchDataFromServer().then((d)=>{ this.responseData = d; }) } } // 你的原有代码 const store = new SomeStore(); let unimportant; autorun(() => { unimportant = store.responseData; }); store.fetchData(); // 此时有订阅者,会执行请求
这个方案简单直接,适合那种需要手动触发请求的场景。
方案二:监听订阅状态自动触发请求
如果想更贴合MobX的响应式思想,推荐用onBecomeObserved和onBecomeUnobserved这两个API,它们可以监听Observable的订阅状态变化:
- 当Observable获得第一个订阅者时,
onBecomeObserved的回调会触发 - 当Observable的最后一个订阅者取消订阅时,
onBecomeUnobserved的回调会触发
实现代码
import { observable, autorun, onBecomeObserved, onBecomeUnobserved } from "mobx"; class SomeStore { @observable responseData; // 用于取消未完成的请求 private abortController?: AbortController; constructor() { // 当responseData被首次订阅时,自动触发请求 onBecomeObserved(this, "responseData", () => { this.fetchData(); }); // 可选:当所有订阅者取消时,取消未完成的请求 onBecomeUnobserved(this, "responseData", () => { this.abortController?.abort(); }); } fetchData(){ // 避免重复发起请求 if (this.abortController) return; this.abortController = new AbortController(); fetchDataFromServer({ signal: this.abortController.signal }) .then((d)=>{ this.responseData = d; }) .finally(() => { this.abortController = undefined; }) } } // 你的原有代码 const store = new SomeStore(); let unimportant; autorun(() => { unimportant = store.responseData; }); // 不需要手动调用fetchData,订阅时会自动触发
这个方案更优雅,完全遵循响应式的逻辑,不用每次调用fetchData都做检查,还能顺便处理请求取消的场景,避免不必要的网络请求。
注意事项
- 这几个API都是MobX的公开稳定API,从MobX 5版本就支持,不用担心兼容性问题
- 如果你用的是MobX 6+,确保你的装饰器配置正确(比如启用
makeObservable或者使用@observable配合useDefineForClassFields)
内容的提问来源于stack exchange,提问作者kaluginserg
相关产品推荐
相关产品推荐

