Vue源码阅读一:说说vue.nextTick实现
用法:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
疑惑:
怎么实现的延迟回调
原理:
- JavaScript语言的一大特点就是单线程,同一个时间只能做一件事
- JavaScript任务可以分为两种,一种是同步任务,一种是异步任务
- 异步任务大致分为,宏任务,和微任务
- 所有同步任务都在主线程上执行,形成一个执行栈
- 主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
- 一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列"中的微任务,其次是宏任务,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
- 主线程不断重复上面的第6步。
vue实现:
vue 大多数情况下优先使用微任务, 很少的地方使用宏任务
vue nextTick 宏任务实现
- 优先检测 setImmediate
if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {macroTimerFunc = () => {setImmediate(flushCallbacks)}
}
复制代码
setImmediate 浏览器支持情况
- 其次检测 MessageChannel 支持情况
else if (typeof MessageChannel !== 'undefined' && (isNative(MessageChannel) ||// PhantomJSMessageChannel.toString() === '[object MessageChannelConstructor]'
)) {const channel = new MessageChannel()const port = channel.port2channel.port1.onmessage = flushCallbacksmacroTimerFunc = () => {port.postMessage(1)}
}
复制代码
MessageChannel 浏览器支持情况
- 上面都不支持就使用最原始的setTimeout
else {/* istanbul ignore next */macroTimerFunc = () => {setTimeout(flushCallbacks, 0)}
}
复制代码
vue nextTick 微任务实现
- 优先检测 Promise
if (typeof Promise !== 'undefined' && isNative(Promise)) {const p = Promise.resolve()microTimerFunc = () => {p.then(flushCallbacks)// in problematic UIWebViews, Promise.then doesn't completely break, but// it can get stuck in a weird state where callbacks are pushed into the// microtask queue but the queue isn't being flushed, until the browser// needs to do some other work, e.g. handle a timer. Therefore we can// "force" the microtask queue to be flushed by adding an empty timer.if (isIOS) setTimeout(noop)}
}
复制代码
Promise 浏览器支持情况
- 如果不支持Promise, 还是使用宏任务
else {// fallback to macromicroTimerFunc = macroTimerFunc
}
复制代码
vue中什么地方用宏任务,什么地方用微任务?
从源码中可以看出,在DOM事件中使用Vue.nextTick 默认使用宏任务, 其他地方使用Vue.nextTick默认使用微任务。
其实从源码中注释中可以看出Vue最开始都是使用微任务方式,后面出现了bug,才引入了宏任务方式
// Here we have async deferring wrappers using both microtasks and (macro) tasks.
// In < 2.4 we used microtasks everywhere, but there are some scenarios where
// microtasks have too high a priority and fire in between supposedly
// sequential events (e.g. #4521, #6690) or even between bubbling of the same
// event (#6566). However, using (macro) tasks everywhere also has subtle problems
// when state is changed right before repaint (e.g. #6813, out-in transitions).
// Here we use microtask by default, but expose a way to force (macro) task when
// needed (e.g. in event handlers attached by v-on).
复制代码
产考资料: JavaScript 运行机制详解:再谈Event Loop
转载于:https://juejin.im/post/5ae2dad851882567105f7bd3
Vue源码阅读一:说说vue.nextTick实现相关推荐
- 推荐一本Vue源码阅读书籍《Vue.js技术内.幕》
1. 概述 这幅图大家应该都很清楚: 但这个过程在Vue框架中是如何实现的呢? 是否考虑过如果是自己,该如何设计呢?而这本<Vue.js技术内幕>就是一本非常好的关于Vue框架源码学习的书 ...
- 【Vue原理】Vue源码阅读总结大会 - 序
[Vue原理]Vue源码阅读总结大会 - 序 阅读源码准备了什么 1.掌握 Vue 所有API 2.JavaScript 扎实基础 3.看完 JavaScript 设计模式 4.学会调试 Vue 源码 ...
- Vue 源码阅读学习(三)
第三节:函数柯里化与渲染模型 嘿,朋友们,本节是 Vue 源码阅读的第三讲.Vue 源码阅读系列得到了赞赏,我很高兴,同时希望大家可以给予反馈!我虚心接纳您的意见! 如果没有看之前的第一讲和第二讲的内 ...
- Vue 源码之手写Vue Router
Vue 源码之手写Vue Router 源码地址:https://github.com/CONOR007/Handwritten-routing 一.Vue Router的两种模式 hash模式实现原 ...
- 【Vue原理】Vue源码阅读总结大会
专注 Vue 源码分享,为了方便大家理解,分为了白话版和 源码版,白话版可以轻松理解工作原理和设计思想,源码版可以更清楚内部操作和 Vue的美,喜欢我就关注我的公众号,好吧兄弟,不会让你失望的 阅读源 ...
- Vue源码分析-手写Vue(简易版)
1.Vue双向绑定/MVVM响应式原理/v-model的原理 vue.js通过数据劫持结合发布订阅者模式,通过Object.defineProperty来劫持各个属性的setter,getter,在数 ...
- Vue 源码阅读(三)Special Attributes
Special Attributes 包括以下:key ref slot v-* key https://vuejs.org/v2/api/#key The key special attribute ...
- Vue源码阅读(12):解析器
今天聊聊解析器,解析器的作用是将程序员编写的模板字符串解析成抽象语法树,抽象语法树可以理解成模板字符串的对象表示形式,其本质并没有什么神奇的,只不过是 JS 中最为常见的对象字面量. 通过抽象语法树, ...
- for里面调用方法 vue_Vue源码阅读连载之Vue实例
我们学习Vue都是从下面这个例子开始的 new Vue({render: h => h(App), }).$mount('#app') 事实上,所有的Vue项目的组成组件都是一个Vue的实例,最 ...
最新文章
- 如何用python画圆形的代码-简单实现python画圆功能
- java接口示例_【基础篇】java-接口及其示例
- HBase 2.0 之修复工具 HBCK2 运维指南
- 表单form数据默认以键值对的形式将数据回发到服务器,回发非纯文本需使用enctype=multipart/form-data方式编码为整条消息...
- 科学计算机看电量,解密:关于手机电量为1%是如何科学的算出来的?
- 其它数据类型和Json的转化
- 七步从Angular.JS菜鸟到专家(2):Scopes
- java新手笔记3 运算符循环
- java取当前日期_java如何获取系统的当前时间
- linux跳转乌班图服务器,Ubuntu18.04连接Linux服务器与文件传输
- day22 正则表达式 re
- kitkat(KRT16S)刷入实机nexus4
- Genymotion启动报错:VT-x/AMD-V硬件加速在您的系统中不可用
- kindeditor 加载 html,为kindeditor编辑器添加“引用”(blockquote)标签
- JAVA家教管理系统毕业设计 开题报告
- 王之泰201771010131《面向对象程序设计(java)》第七周学习总结
- Windows 7 安装软件错误:“Error 1935 ...HRESULT: 0x800736FD” 的解决办法
- 在tensorflow下进行pip操作时需要注意的地方
- 中兴echat_在追随用户的路上创新不止 — 中兴高达mini eChat解决方案
- 品•文案——聊聊产品文案优化设计
热门文章
- 宝宝安全座椅什么牌子好?[自己参考]
- [vb]SendMessageA函数
- 斯坦福大学2019年NLP课程上线,下周二开课 | 附PPT+视频
- 雷军振臂一呼:1亿小爱同学激活是不是中国第一?百度硬刚:我才是
- 再谈“炼金术”:可以使用不严谨的方法,但拒绝不严谨的评估方法
- 软件2.0时代来了!特斯拉AI负责人说:神经网络正在改变编程
- mapreduce中文乱码,已解决
- 排序算法与常见数据结构
- 高逼格又实用的Linux命令:持续更新中
- Higher level thinking