vue中nexttick原理是什么?一文带你看懂nexttick的使用
Admin 2021-10-23 群英技术资讯 741 次浏览
vue中nexttick原理是什么?如果有使用过vue的朋友应该知道,vue里面的nextTick可以获取到更新后的DOM,但一些朋友并不清楚nextTick里面究竟做了什么,因此本文我们就来了解一下vue中nexttick原理。
开始讲解前,我们需要知道了解一个概念,那就是Event Loop
Event Loop翻译过来就是事件循环, 一个Event Loop会包括一个或多个task队列,持续线程会从队列中取出最早进入队列的任务进行执行,被取出的任务就叫做macroTask(宏任务), 每个macroTask都有一个任务源, 每个macroTask处理完之后就从队列中取出下一个时间最早进入的macroTask再重执行
任务源:
``` 1. script 2. 事件 3. Dom交互 4. I/O 5. UI Render 6. setTimeout 7. setInterval 8. requestAnimationFrame ..... ```
也就是说碰到以上几种情况就会产生一个macroTask并且推入到队列中
执行完每个macroTask之后,主线程会去检查该macroTask下的microTask是否为空,如果不为空,则按照时间顺序从早到晚取出,如果途中有遇到新的microTask, 那么会继续将该microTask推入到microTask队列里
伴随着miscroTask队列的清空,主线程就会执行UI Render, 也就是渲染界面,但是浏览器它并不会每次在UI Render任务下一定会渲染界面,视情况而言,现在主流浏览器一般都是按照60HZ 也就是16.7ms刷新频率进行渲染(不是精确估量),一个macroTask通常是小于16.7ms, 所以浏览器每次会根据情况进行渲染
1. 从macroTask队列里取出最早添加进去的
2. 开始执行task, 途中如果遇到新的macroTask,就会将其添加到macroTask队列的最后面
3. 执行完macroTask之后,event loop会去寻找microTask队列
4. 同样的道理,如果途中遇到新的microTask,将其放入该macroTask下的microTask队列最后面
5. 执行完microTask,会执行UI Render macroTask
6. 浏览器会根据现有情况决定是否更新DOM,通常是按照60HZ的频率去更新
7. 至此,一个event loop结束了
我们开始分析nextTick
根据上图
我们看到nextTick的几种写法:
1. this.$nextTick(cb) 2. this.$nextTick().then(cb)
所有的cb都会被放入到callbacks数组里,等待一次性调用
上图中我们看到了主要是由timerFunc这个函数来进行调用回调, 那么我们下面来着重介绍这个函数,首先看下源码
我们可以看到timerFunc在不同情况下不同的赋值情况
首先会判断浏览器是否支持promise属性, 如果支持, timerFunc就会被赋值成Promise, 这里有个小小的问题,那就是在ios下,虽然是具备Pormise对象,并且会将它推入到microTask队列里,但是队列却不会更新,这个时候需要添加一个macroTask来强制刷新microTask队列
MutationObserver, 相信很多人并不清楚这个Api, 这是一个能够监听DOM变化的API,并且属于microTask, 优先级低于Promise 在创建一个新的文本节点后,手动更改其文本节点来触发microTask,
这里会有个小小的问题:
该文本节点渲染成功后,一定能代表其他的DOM渲染成功了吗?
这是个备选方案, 主要还是因为它是一个微任务,所以才使用它,并不是因为它监听了DOM
微任务都失败后, 退而求其次,选择setImmediate, 这是一个只有高版本IE和Edge浏览器才可能拥有的API, 其主要是用于计算大量数据的时候使用
最后就是setTimeout
看到这里,你会不会有疑惑?
上面的代码并没有说明nextTick是在监听DOM更新后才执行的? What????当时脑袋就duang了一下
那么接下来说的就是重中之重
DOM Tree的更新是实时的,DOM Tree的更新是实时的,DOM Tree的更新是实时的, 重要的事说3遍, 这意味着你无需去监听DOM 更新, 你对DOM的操作是能够实时得到反馈的,上一行代码操作了DOM,下一行就能获取到
那么有人就会产生疑惑了, nextTick究竟是干嘛的?
nextTick的作用是将收集Watcher从队列中一个个取出,并且更改数据,来一次性渲染DOM, 我们知道操作DOM的代价是昂贵的, 浏览器打开一个网页后会开启一个进程,进程是由线程组成的,
1. GUI渲染线程
2. js引擎线程(主线程)
3. EventLoop轮训处理线程
4. 其他线程,例如网络
跨线程操作代价是昂贵的,所以做到一次性渲染Dom,可以有效的优化性能!!
nextTick并不是用来监听DOM变更,因为DOM变更是能够实时获取到的,它的作用是一次性更改数据,并且渲染DOM
关于vue中nexttick原理就介绍到这,本文有很详细的介绍,感兴趣的朋友可以了解看看,希望能对大家有帮助,想要了解更多nexttick的内容,大家可以关注其它的相关文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于number类型的相关知识,包括了number类型的常见误区背后原理以及解决方法等内容,下面一起来看一下,希望对大家有帮助。
vue怎样自动导入公共组件?其实想要实现自动导入公共组件并不困难,但是有一些问题以及规则需要注意,下面小编就给大家介绍一下vue导入公共组件的方法和步骤。
JS的原型对象是什么?很多新手对于原型对象可能不是很了解,下面小编就给大家介绍一下什么是原型,与原型有关的属性和方法有哪些,以及怎样创建原型对象,感兴趣的朋友就接着往下看吧。
对于JavaScript的语法以及实现大家应该都有一定的了解了,但是对于JavaScript的预编译有很多人是不太清楚的,下面就从语法分析,预编译,解释执行这三步骤给大家介绍一下JavaScript的预编译。
这篇文章主要介绍了JavaScript时间复杂度和空间复杂度,时间复杂度和空间复杂度是衡量一个算法是否优秀的标准,通常我们比较两个算法时会用预先估算和事后统计,下文详细介绍,需要的朋友可以参考一下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008