vue3在处理effect更新时,使用事件队列,减少重复操作一个对象上的多次更新。
<script src="https://unpkg.com/vue"></script><div id="app"></div><script>const { h, createApp, reactive } = Vue;let App = {setup(props, context) {let state = reactive({ name: "aaa" });let changeFn = () => {state.name = "bbb";state.name = "aaa";state.name = "ccc";state.name = "bbb";};return () => {return h("div", { onClick: changeFn }, state.name);};},};let app = createApp(App).mount("#app");</script>
以上代码对name进行多次更改值操作,如果没有事件调度使用,那么会进行4次更新渲染。使用调度器,把相同的任务放到一个queue中,如果事件job存在就不进行添加。
文件在runtime-core的scheduler.ts中。
// 任务队列,先去重,在依次调用let queue = [];export function queueJob(job) {if (!queue.includes(job)) {queue.push(job);// 多个任务,只执行一次queueFlush();}}let isFlushPending = false;function queueFlush() {if (!isFlushPending) {isFlushPending = true;// 把队列中的任务,一下同时完全调用Promise.resolve().then(flushJobs);}}function flushJobs() {isFlushPending = false;// 按照事件的id进行排序queue.sort((a, b) => a.id - b.id);for (let i = 0; i < queue.length; i++) {const job = queue[i];job();}queue.length = 0;}
