跳到主要内容

认识

2023年06月10日
柏拉文
越努力,越幸运

一、认识


Scheduler 调度器 用于处理 Vue异步更新 或者 批量更新

我们的数据通过 Object.defineProperty 为对象的每个 key 设置 gettersetter,从而拦截对数据的访问和设置。

当对数据进行更新操作时,比如 obj.key = 'new val' 就会触发 setter 的拦截,从而检测新值和旧值是否相等,如果相等什么也不做,如果不相等,则更新值,然后由 dep 通知 watcher 进行更新。所以,异步更新 或者 批量更新 的入口点就是 setter 中最后调用的 dep.notify() 方法。

异步更新批量更新是如何实现的?

Vue异步更新机制的核心是利用了浏览器的异步任务队列来实现的,首选微任务队列宏任务队列次之。

  1. 当响应式数据更新后,会调用 dep.notify 方法,通知 dep 中收集的 watcher 去执行 update 方法,watcher.updatewatcher 自己放入一个 watcher 队列(全局的 queue 数组)。

  2. 然后通过 nextTick 方法将一个刷新 watcher 队列的方法(flushSchedulerQueue)放入一个全局的 callbacks 数组中。

  3. 如果此时浏览器的异步任务队列中没有一个叫 flushCallbacks 的函数,则执行 timerFunc 函数,将 flushCallbacks 函数放入异步任务队列。如果异步任务队列中已经存在 flushCallbacks 函数,等待其执行完成以后再放入下一个 flushCallbacks 函数。

  4. flushCallbacks 函数负责执行 callbacks 数组中的所有 flushSchedulerQueue 函数。

  5. flushSchedulerQueue 函数负责刷新 watcher 队列,即执行 queue 数组中每一个 watcherrun 方法,从而进入更新阶段,比如执行组件更新函数或者执行用户 watch 的回调函数。

二、细节