当前位置: 首页 > 后端技术 > PHP

你不知道$nextTick

时间:2023-03-29 23:45:05 PHP

在代码中什么时候更新了数据,你想等到对应的Dom更新了,再执行一些逻辑。这时候我们会使用$nextTickfuncioncallback(){//等待Dom更新,然后做一些事情。}$nextTick(回调);复制代码官方文档对nextTick的解释如下:延迟回调在下一个DOM更新周期结束后执行。修改数据后立即使用此方法获取更新后的DOM。那么,Vue是如何做到这一点的呢?是不是在调用了修改Dom的Api(appendChild,textContent="xxxxx"等等)之后调用了我们的回调函数?到底发生了什么。源码nextTick的实现逻辑在这个文件:vue/src/core/util/next-tick.js我们调用的this.$nextTick其实就是这个方法:exportfunctionnextTick(cb?:Function,ctx?:Object){let_resolvecallbacks.push(()=>{if(cb){try{cb.call(ctx)}catch(e){handleError(e,ctx,'nextTick')}}elseif(_resolve){_resolve(ctx)}})if(!pending){pending=truetimerFunc()}//$flow-disable-lineif(!cb&&typeofPromise!=='undefined'){returnnewPromise(resolve=>{_resolve=resolve})}}复制代码,可以看到回调函数存储在一个数组中:callbacks。如果没有传回调函数,这个方法会返回一个Promise,然后将reslove作为回调函数放到flushCallbacks中。所以文档说明了把应该作为回调函数使用的回调放到then中的用法。然后,有一个名为挂起的变量。如果不是pending,函数timerFunc将被执行。而pending默认等于false。flushCallbacks函数将一次性执行所有回调函数。timerFunctimerFunc在这里定义。您可以看到timerFunc在已解析的Promise的then中执行了flushCallbacks。它使用了js事件循环的microtask机制。因此,每当我们调用$nextTick时,如果pending为false,就会调用timerFunc,然后timerFunc会把flushCallbacks放在事件循环的最后,等待调用。if(typeofPromise!=='undefined'&&isNative(Promise)){constp=Promise.resolve()timerFunc=()=>{p.then(flushCallbacks)}}复制代码flushCallbacks然后也在这个文件中一个名为:flushCallbacks的函数用于完全执行和清除保存的回调函数。functionflushCallbacks(){pending=falseconstcopies=callbacks.slice(0)callbacks.length=0for(leti=0;i