网站备案变更公司名称,统计局门户网站建设目标,网站建设基础知识,自己怎么做返利网站吗前言
在上一篇 如何理解 vue 响应式#xff1f; 中#xff0c;了解到响应式其实是通过 Observer 类中调用 defineReactive() 即 Object.defineProperty() 方法为每个目标对象的 key#xff08;key 对应的 value 为非数组的#xff09; 设置 getter 和 setter 实现拦截 中了解到响应式其实是通过 Observer 类中调用 defineReactive() 即 Object.defineProperty() 方法为每个目标对象的 keykey 对应的 value 为非数组的 设置 getter 和 setter 实现拦截分别进行 依赖收集 和 依赖更新通知而 vue 的异步更新就在 setter 中的 dep.notify() 之后进行开启.
深入源码
下面针对源码的解读内容都在源码对应截图的注释中就不在进行单独描述.
dep.notify() 方法 watcher.update() 方法 queueWatcher() 方法 flushSchedulerQueue() 方法 watcher.run() 方法 watcher.get() 方法 nextTick() 方法 timerFunc() 方法
timerFunc() 其实就是利用了浏览器的异步任务队列去执行 flushCallbacks() 方法这整个过程其实就是 优雅降级
首先判断当前环境是否支持 Promise如果支持就用 Promise 来触发回调函数如果不支持 Promise 就判断是否支持 MutationObserver通过观察文本节点发生变化去触发执行异步回调函数如果不支持 MutationObserver 就判断是否支持 setImmediate如果支持就通过 setImmediate 来触发回调函数如果以上都不支持就只能用 setTimeout 来完成异步执行 关于 Promise、MutationObserver、浏览器异步任务 等内容如果你还不算足够了解那么在文末会给出的对应文章链接以提供大家去学习和深入了解. flushCallbacks() 方法
flushCallbacks() 方法会去清空 callbacks 数组并执行所有在 nextTick() 中保存的函调函数.
总结
vue 中如何实现异步更新
vue 中的异步更新机制主要是利用了 浏览器的异步任务队列 来实现的首选 微任务队列其次选 宏任务队列。
当响应式数据发生更改后会在 setter 中调用 dep.notify 方法通知 dep 中收集的所有 watcher 执行更新即调用 watcher.update 方法这个方法会把当前 watcher 加入到全局的 watcher 队列 queue其实就是数组。
然后通过 nextTick 方法把 刷新 watcher 队列的方法即 flushSchedulerQueue() 添加到全局的 callbacks 数组当中。
如果当前浏览器的异步任务队列中 不存在 flushCallbacks 函数就通过 timerFunc 方法使用异步去执行 flushCallbacks 方法这个方法会把 callbacks 清空并执行里面所有 flushSchedulerQueue 函数。
如果当前浏览器的异步任务队列中 存在 flushCallbacks 函数那么就会等待当前异步队列中的 flushCallbacks 函数执行完成后在加入下一个 flushCallbacks 函数。
其中负责刷新 watcher 队列的 flushSchedulerQueue() 函数就会执行 queue 队列中的每个 watcher.run() 方法从而进入更新阶段如执行组件的更新函数 updateComponents 或执行用户 watch 回调。
vue 中的 nextTick 原理是什么
Vue-nextTick 在官方文档解释中是用于在下次 DOM 更新循环结束之后执行延迟回调在修改数据之后立即使用这个方法获取更新后的 DOM。
在 nextTick 中会把接收的回调函数 cb 使用 try catch 进行包裹目的是方便进行异常捕获之后会把这个 cb 存入到 全局的 callbacks 数组中执行 timerFunc通过浏览器的异步循环队列去执行 flushCallbacks 函数清空 callbacks 数组并执行里面的回调函数