我有一个具有 BehaviorSubject 和 Observable 的 js 类。我想在不同的类中订阅 Observable,但它不能正常工作。
//class One:
export default ClassOne {
constructor(){
this._store = new BehaviorSubject({});
this.store = this._store.asObservable();
this.store.subscribe(data => {console.log(data)}) //logs the data, no Problem here
//{};{ test: { foo: "bar", max: "muster" } };{ test: { foo: "bar", max: "muster" } };...
}
addData(data){ this._store.next(data)} //iscalled a few times.
getStore () {return this.store} //using a getter Function does not work either
}
//class Two
import class1 from "./class1";
ClassTwo {
constructor(){
this.one = new ClassOne();
this.one.store.subscribe(data =>{console.log(data)}) //only logs {} once. Is never fired again.
this.one.getStore().subscribe(data =>{console.log(data)}) //Same Problem
}
}
所以我的主要问题是:如何确保订阅者获得 ClassTwo 中的所有更改?
请注意,Observable 已定义并触发一次,但不会收到新更改的通知。
当 ClassOne 是单例时,它有什么不同吗?:
//class One:
instance = null;
export default ClassOne {
constructor(){
if (instance === null) {
instance = this;
}
instance._store = new BehaviorSubject({});
instance.store = this._store.asObservable();
instance.store.subscribe(data => {console.log(data)}) //logs the data, no Problem here
}
addData(data){ instance._store.next(data)} //iscalled a few times.
getStore () {return instance.store} //using a getter Function does not work either
}
编辑:测试它是否为单例
(开玩笑)
beforeAll(() => {
one = new ClassOne();
});
test("Singleton Test", () => {
let one2 = new ClassOne();
expect(one2 instanceof ClassOne).toEqual(true);
expect(one2).toEqual(one);
expect(one2 === one).toEqual(true);
});
Edit2:使用添加数据
beforeAll(() => {
one = new ClassOne();
two = new ClassTwo();
});
test("", (done) => {
one.addData({ test: { foo: "bar", max: "muster" } });
one.addData({ test: { foo: "bar", max: "muster" } });
one.addData({ test: { foo: "bar", max: "muster" } });
//I just coded this by heart, but the test is somthing like this
expect(one.getStore()).toEqual(two.one.store);
//makes sure that the subscriber have enough time
setTimeout(() => done(), 5000);
}, 6000);
编辑 3:使用 share/shareReplay
我更改了 getStore() 函数:
//ClassOne
getStore(){ return instance.store.pipe(share()) }
//and I tried:
getStore(){ return instance.store.pipe(shareReplay()) }
//ClassTwo:
this.one.getStore().subscribe(data =>{console.log(data)})
但问题仍然存在。
Edit4:一些故障排除
因此,经过一些测试和阅读后,我得出结论,构造函数中的订阅无法正常工作。
虽然这不起作用:
let two = new ClassTwo(); //with the subscription on the store
这有效:
let two = new ClassTwo(); //without the subscription on the store
two.subscribeToMyStore();
//subscribeToMyStore:
subscribeToMyStore(){
this.one.store.subscribe(data =>{console.log(data)})
}
那么为什么我不能在构造函数中进行订阅呢?
为什么它会订阅 ClassOne 而不是 ClassTwo 的构造函数?
最佳答案
你必须重复使用一样的实例。要么确保它是单例并使用一些 DI 框架通过构造函数注入(inject),要么自己从单独的模块中导出单例,不要忘记 share它。请注意,shareReplay 时存在相当流行的场景。是需要的。
关于javascript - rxjs:订阅者不会触发不同类中的所有更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61887746/