异步更新队列
vue高效的秘诀是一套批量,异步的更新策略
在程序中有好多个组件,每个组件对应一个watch实例,在一次事件循环更新周期内,可能有好多数据发生变化,可能每个组件都会变,这时候最好的方式就是将组件批量的一次更新完之后,浏览器再刷新页面,这时候是最高效的做法
概念
- 事件循环:浏览器为了协调事件处理、脚本执行、网络请求和渲染等任务而制定的一套工作机制。
- 宏任务:代表一个个离散的、独立工作单元。浏览器完成一个宏任务,在下一个宏任务执行开始前,会对页面进行重新渲染。主要包括创建主文档对象、解析HTML、执行主线JS代码以及各种事件如页面加载、输入、网络事件和定时器等。
- 微任务:微任务是更小的任务,是在当前宏任务执行结束后立即执行的任务。如果存在微任务,浏览器会清空微任务之后再重新渲染。微任务的例子有 promise 回调函数(异步回调函数)、DOM发生变化、watch的update函数等。
总结:
- 在执行一次宏任务之后,看有没有微任务,有微任务,就清空微任务之后浏览器再刷新页面,没有微任务就直接刷新页面
- 先做同步任务,再做异步任务,把call stack给清空掉
vue中的具体实现
-
异步:只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。
-
批量:如果同一个 watcher 被多次触发,只会被推入到队列中一次。去重对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列执行实际工作。
-
异步策略:Vue 在内部对异步队列尝试使用原生的 Promise.then 、 MutationObserver 和setImmediate ,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。
-
\src\core\observer\index.js 中的dep.notify()
-
\src\core\observer\watcher.js 中的update()中的queueWatcher(this)
-
\src\core\observer\scheduler.js 中的queueWatcher函数 nextTick()
-
\src\core\util\next-tick.js timerFunc()异步函数
是run()方法执行更新的,不是update()方法
来源:CSDN
作者:佛系孤单
链接:https://blog.csdn.net/qq_43427385/article/details/104276400