认识
一、认识
Scheduler
调度器 用于处理 Vue
的 异步更新 或者 批量更新。
我们的数据通过 Object.defineProperty
为对象的每个 key
设置 getter
、setter
,从而拦截对数据的访问和设置。
当对数据进行更新操作时,比如 obj.key = 'new val'
就会触发 setter
的拦截,从而检测新值和旧值是否相等,如果相等什么也不做,如果不相等,则更新值,然后由 dep
通知 watcher
进行更新。所以,异步更新 或者 批量更新 的入口点就是 setter
中最后调用的 dep.notify()
方法。
异步更新或批量更新是如何实现的?
Vue
的异步更新机制的核心是利用了浏览器的异步任务队列来实现的,首选微任务队列,宏任务队列次之。
-
当响应式数据更新后,会调用
dep.notify
方法,通知dep
中收集的watcher
去执行update
方法,watcher.update
将watcher
自己放入一个watcher
队列(全局的queue
数组)。 -
然后通过
nextTick
方法将一个刷新watcher
队列的方法(flushSchedulerQueue
)放入一个全局的callbacks
数组中。 -
如果此时浏览器的异步任务队列中没有一个叫
flushCallbacks
的函数,则执行timerFunc
函数,将flushCallbacks
函数放入异步任务队列。如果异步任务队列中已经存在flushCallbacks
函数,等待其执行完成以后再放入下一个flushCallbacks
函数。 -
flushCallbacks
函数负责执行callbacks
数组中的所有flushSchedulerQueue
函数。 -
flushSchedulerQueue
函数负责刷新watcher
队列,即执行queue
数组中每一个watcher
的run
方法,从而进入更新阶段,比如执行组件更新函数或者执行用户watch
的回调函数。