跳转到内容

Schedule

Schedule 用于合并或延迟通知,避免高频写入造成的渲染抖动。

  • 本质:只改变“通知时机”,不改变最终状态值。
  • 价值:减少同一事件循环内的重复通知。
  • 场景:连续写入、动画更新、批量同步后的 UI 刷新。
  • 多次连续 set() 会触发过多订阅回调。
  • 你可以接受“下一微任务”或“下一帧”再通知。
  • 你希望把写入频率与渲染频率解耦。
import { io } from '@iostore/store';
import { schedule, withBehaviors } from '@iostore/store/behavior';
const count = io(0);
const view = withBehaviors(count, [schedule('microtask')]);
view.subscribe((value) => {
console.log('notified', value);
});

你可以尝试一次触发多次写入,对比 syncmicrotask 的通知次数差异。

同样 10 次连续写入:
触发次数:0
`schedule('sync')` 累计通知次数:0
`schedule('microtask')` 累计通知次数:0
import { useEffect, useState } from 'react';
import { io } from '@iostore/store';
import { schedule, withBehaviors } from '@iostore/store/behavior';
const syncStore = io(0);
const microtaskStore = io(0);
const syncView = withBehaviors(syncStore, [schedule('sync')]);
const microtaskView = withBehaviors(microtaskStore, [schedule('microtask')]);
function ScheduleLiveDemo() {
const [runs, setRuns] = useState(0);
const [syncNotifies, setSyncNotifies] = useState(0);
const [microtaskNotifies, setMicrotaskNotifies] = useState(0);
useEffect(() => {
const offSync = syncView.subscribe(() => setSyncNotifies((n) => n + 1));
const offMicrotask = microtaskView.subscribe(() =>
setMicrotaskNotifies((n) => n + 1),
);
return () => {
offSync();
offMicrotask();
};
}, []);
const burstUpdate = () => {
setRuns((n) => n + 1);
for (let i = 1; i <= 10; i += 1) {
syncStore.set(i);
microtaskStore.set(i);
}
};
return (
<section className="io-live">
<div>同样 10 次连续写入:</div>
<div>触发次数:{runs}</div>
<div>`schedule('sync')` 累计通知次数:{syncNotifies}</div>
<div>`schedule('microtask')` 累计通知次数:{microtaskNotifies}</div>
<button type="button" className="io-live__button" onClick={burstUpdate}>
执行 10 次连续 set
</button>
</section>
);
}
export default ScheduleLiveDemo;

观察点:microtask 会把同一事件循环内的通知合并,而 sync 会逐次触发通知。

  • sync:立即通知。
  • microtask:同一事件循环合并通知。
  • animationFrame:下一帧前通知(可用时)。
  • schedule 当节流/防抖:它控制时机,不做时间窗口频控。
  • 对强实时链路仍使用 microtask/animationFrame:可能引入可见延迟。
  • 与大量离散写入配合却不做批处理:仍可能产生冗余通知。
  • 默认从 microtask 开始,必要时再切到 syncanimationFrame
  • Batching 组合,先合并写入再调度通知。
  • 在复杂链路中明确“谁负责调度”,避免多层重复调度。