我有一个Meteor ReactiveVar
,它被用作数据存储中的更新触发器。然而,跟踪器并不是每次设置响应变量时都运行。
似乎有时当状态被快速连续设置时,跟踪器不运行。
这是我的商店代码:
const myStore = {
states = {
...
},
updateTrigger = new ReactiveVar({ name: null, timeStamp: null }),
setState({ name, value }) {
this.states[name] = value;
console.log('Set State', name);
this.updateTrigger.set({ name, timeStamp: new Date().getTime() });
},
};
和跟踪器:
Tracker.autorun(() => {
const updateTrigger = myStore.updateTrigger.get();
console.log('Tracker', updateTrigger.name);
if (updateTrigger.name === state-two) myFunction();
});
控制台记录如下:
'Set State state-one' // update state-one
'Tracker state-one'
'Set State state-two' // update state-two
'Set State state-one' // update state-one
'Tracker state-one'
'Set State state-three' // update state-three
'Tracker state-three'
'Set State state-one' // update state-one
'Set State state-two' // update state-two
'Set State state-three' // update state-three
'Tracker state-three'
我不明白为什么会发生这种事。
这似乎是一个竞争条件,因为它不区分哪些更新记录,哪些更新不记录。
状态更新非常频繁(每1.5s更新一次状态,然后其他状态大约每秒更新一次)。
欢迎任何关于哪里出了问题或其他方法的建议。
我可以使用PubSub包。一般来说,我不是Tracker
和ReactiveVar
的大粉丝,但我不确定这里的最佳实践是什么,我不想在某些地方使用Tracker
+ ReactiveVar
,而在其他地方使用PubSub。
将每个单独的状态作为ReactiveVar
不是一个选项,因为我需要在更新时将状态持久化到数据库。
这是由于跟踪器的刷新周期。
从跟踪器手册:
…默认情况下,所有对响应值的更改都是批处理的并在所有JavaScript代码执行完毕并且系统空闲时立即生效. ...这个过程…,也可以通过调用
Tracker.flush()
手动触发。
因此,在代码中添加显式刷新将产生期望的效果:
const myStore = {
states = {
...
},
updateTrigger = new ReactiveVar({ name: null, timeStamp: null }),
setState({ name, value }) {
this.states[name] = value;
console.log('Set State', name);
this.updateTrigger.set({ name, timeStamp: new Date().getTime() });
Tracker.flush(); // added this
},
};