functionqueueWatcher(watcher){var id = watcher.id;// has用来保存watcher的idif(has[id]==null){
has[id]=true;// 当flushing不为true,也就是flushSchedulerQueue()不在执行,直接pushif(!flushing){
queue.push(watcher);}else{// 正在fulshing,执行queue中的watcher:按id升序插入queue中未执行的剩余队列中。找到满足下列两个条件之一的位置:// 1. [i--].id < [i].id < [i++].id位置// 2. 如果按顺序应该插入的位置已经过了。即不满足i>index; index是当前执行到的watcher在数组中的下标。// if already flushing, splice the watcher based on its id// if already past its id, it will be run next immediately.var i = queue.length -1;while(i > index && queue[i].id > watcher.id){
i--;}
queue.splice(i +1,0, watcher);}// queue the flushif(!waiting){
waiting =true;if(!config.async){flushSchedulerQueue();return}nextTick(flushSchedulerQueue);}}}
flushSchedulerQueue() 函数对watcher进行排序并执行
functionflushSchedulerQueue(){
currentFlushTimestamp =getNow();
flushing =true;var watcher, id;// Sort queue before flush.// This ensures that:// 1. Components are updated from parent to child. (because parent is always// created before the child)// 2. A component's user watchers are run before its render watcher (because// user watchers are created before the render watcher)// 3. If a component is destroyed during a parent component's watcher run,// its watchers can be skipped.
queue.sort(function(a, b){return a.id - b.id;});// do not cache length because more watchers might be pushed// as we run existing watchersfor(index =0; index < queue.length; index++){
watcher = queue[index];if(watcher.before){
watcher.before();}
id = watcher.id;
has[id]=null;
watcher.run();// in dev build, check and stop circular updates.if(has[id]!=null){
circular[id]=(circular[id]||0)+1;if(circular[id]>MAX_UPDATE_COUNT){warn('You may have an infinite update loop '+(
watcher.user
?("in watcher with expression \""+(watcher.expression)+"\""):"in a component render function."),
watcher.vm
);break}}}// keep copies of post queues before resetting statevar activatedQueue = activatedChildren.slice();var updatedQueue = queue.slice();resetSchedulerState();// call component updated and activated hookscallActivatedHooks(activatedQueue);callUpdatedHooks(updatedQueue);// devtool hook/* istanbul ignore if */if(devtools && config.devtools){
devtools.emit('flush');}}