Tracker.autorun()不会在每次更新一个ReactiveVar时运行



我有一个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包。一般来说,我不是TrackerReactiveVar的大粉丝,但我不确定这里的最佳实践是什么,我不想在某些地方使用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
    },
};

相关内容

最新更新