queueWatcher
queueWatcher方法在每次派发更新的时候都会被调用,传入的是watcher实例。在vue中视图更新是异步的,并且内部维护了一个更新队列queue,一个去重后的watcher集合,两个状态:flushing(队列是否更新中)和waiting(是否开启排队)
这里要注意的是在开启flushing后,新加入watcher的插队及nextTick
flushSchedulerQueue
这里的关键点是queue的排序原因。
Tick
JS是单线程语言,如果所有的函数都是同步执行的,那么必然会导致线程的阻塞,因此有了event loop的方法来解决阻塞的问题。
在红宝书中能见到有提到tick的概念,每一轮事件循环完成之后,被称为一个tick。那么nextTick就是下一个event loop的意思了。也就是异步执行。
下图为事件循环的示意图
Event loop
宏任务:
I/O(文件,网络等)
setTimeout
setInterval
setImmediate
requestAnimationFrame
脚本文件也可以看成一个红任务。
微任务
process.nextTick
promise
MutationObserver
Vue中的nextTick
nextTick核心为 timerFunc函数
timerFunc
v2.6.11版本的异步更新策略
flushCallbacks
细节是拷贝callbacks,然后重置pending的状态,
callbacks是全局唯一的,不像watcher更新的时候queuewacher队列还可以插队。
之前的插队行为应该是为了提升性能,讲更新任务做成异步的,然后再每次更新过程中最大可能地收集更新行为。
而这里的nextTick没有用插队的方式,如果用了那就不能将任务切片了。和同步也没什么差别。