当前位置: 首页 > Web前端 > vue.js

VuenextTick源码分析

时间:2023-03-31 21:43:59 vue.js

1.当nextTick被执行时,回调函数将被添加到数组中。当没有微任务(microtask),即panding为false时,通过调用timerFunc创建一个微任务。Microtasks会在当前执行栈为空后执行(解释为什么改变数据后页面没有立即更新)。microtask会调用flushCallbacks,设置pending为true,表示microtask正在执行,下一个nextTick需要重新创建microtask,然后依次执行之前收集的回调函数。varcallbacks=[];//微任务中将调用的方法集varpending=false;//是否创建微任务vartimerFunc;//创建微任务的函数functionnextTick(cb,ctx){变种_解决;callbacks.push(function(){//将返回函数添加到数组中,将在微任务中执行if(cb){try{cb.call(ctx);}catch(e){handleError(e,ctx,'nextTick');}}elseif(_resolve){_resolve(ctx);}});if(!pending){//没有微任务挂起=true;timerFunc();//创建微任务}...}varp=Promise.resolve();timerFunc=function(){p.then(flushCallbacks);//创建一个microtask,在microtask中调用之前收集的回调函数};functionflushCallbacks(){pending=false;//微任务已经执行varcopies=callbacks.slice(0);回调.length=0;for(vari=0;iindex&&queue[i].id>watcher.id){//插入到当前正在处理的wacher的后面,id刚好大于之前的idi--;}queue.splice(i+1,0,观察者);//根据id的大小插入到wacherInsidetheprocessingwatch}//flush入队if(!waiting){waiting=true;if(process.env.NODE_ENV!=='production'&&!config.async){flushSchedulerQueue();返回}nextTick(flushSchedulerQueue);}}}3.flushSchedulerQueue函数会被添加到微任务数组中,当微任务执行时会被调用。按照id从小到大排序,然后执行update方法(watcher.run),保证先执行parentwatcher的update方法,再调用childwatcher的update方法。执行完所有update方法后清空数组,waiting和flushing设置为false,分别表示下次需要在数组中加入flushSchedulerQueue进行microtask执行,当前不在执行update的状态方法(您可以直接将观察者添加到数组中)。最后执行观察者更新激活的生命周期函数。函数flushSchedulerQueue(){currentFlushTimestamp=getNow();冲洗=真;变量观察者,id;//刷新前排序队列。//这确保://1.组件从父级更新到子级。(因为父对象总是//在子对象之前创建)//2.组件的用户观察者在其渲染观察者之前运行(因为//用户观察者在渲染观察者之前创建)//3.如果一个组件在一个组件被销毁父组件的观察者运行,//它的观察者可以被跳过。queue.sort(function(a,b){returna.id-b.id;});//从小到大顺序//不要缓存长度,因为更多的watchers可能会被推送//因为我们运行现有的watchersfor(index=0;index