Tracker.autorun() 而不是 运行 每次更新 ReactiveVar

Tracker.autorun() not running on every update of a ReactiveVar

我有一个 Meteor ReactiveVar,用作数据存储中的更新触发器。但是,每次设置反应性变量时,跟踪器都不会 运行。

好像有时候状态设置的很快,tracker 不会运行.

这是我商店的代码:

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.5 秒状态一次,然后其他每秒左右)。

欢迎就问题所在或其他方法提出任何建议。

我可以使用 PubSub 包。一般来说,我不是 TrackerReactiveVar 的忠实粉丝,但我不确定这里的最佳做法是什么,我不想使用 Tracker+ReactiveVar 在某些地方,在其他地方是 PubSub。

将每个单独的状态作为 ReactiveVar 不是一种选择,因为我需要在更新时将状态持久保存到数据库中。

这是由于 Tracker's Flush Cycle

来自跟踪器手册:

... by default, all changes to reactive values are batched up and put into effect all at once, when all JavaScript code has finished executing and the system is idle. ... This process ... is called flushing, and it's also possible to manually trigger it by calling 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
    },
};