用法:

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

疑惑:

怎么实现的延迟回调

原理:

  1. JavaScript语言的一大特点就是单线程,同一个时间只能做一件事
  2. JavaScript任务可以分为两种,一种是同步任务,一种是异步任务
  3. 异步任务大致分为,宏任务,和微任务
  4. 所有同步任务都在主线程上执行,形成一个执行栈
  5. 主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
  6. 一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列"中的微任务,其次是宏任务,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
  7. 主线程不断重复上面的第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实现相关推荐

  1. 推荐一本Vue源码阅读书籍《Vue.js技术内.幕》

    1. 概述 这幅图大家应该都很清楚: 但这个过程在Vue框架中是如何实现的呢? 是否考虑过如果是自己,该如何设计呢?而这本<Vue.js技术内幕>就是一本非常好的关于Vue框架源码学习的书 ...

  2. 【Vue原理】Vue源码阅读总结大会 - 序

    [Vue原理]Vue源码阅读总结大会 - 序 阅读源码准备了什么 1.掌握 Vue 所有API 2.JavaScript 扎实基础 3.看完 JavaScript 设计模式 4.学会调试 Vue 源码 ...

  3. Vue 源码阅读学习(三)

    第三节:函数柯里化与渲染模型 嘿,朋友们,本节是 Vue 源码阅读的第三讲.Vue 源码阅读系列得到了赞赏,我很高兴,同时希望大家可以给予反馈!我虚心接纳您的意见! 如果没有看之前的第一讲和第二讲的内 ...

  4. Vue 源码之手写Vue Router

    Vue 源码之手写Vue Router 源码地址:https://github.com/CONOR007/Handwritten-routing 一.Vue Router的两种模式 hash模式实现原 ...

  5. 【Vue原理】Vue源码阅读总结大会

    专注 Vue 源码分享,为了方便大家理解,分为了白话版和 源码版,白话版可以轻松理解工作原理和设计思想,源码版可以更清楚内部操作和 Vue的美,喜欢我就关注我的公众号,好吧兄弟,不会让你失望的 阅读源 ...

  6. Vue源码分析-手写Vue(简易版)

    1.Vue双向绑定/MVVM响应式原理/v-model的原理 vue.js通过数据劫持结合发布订阅者模式,通过Object.defineProperty来劫持各个属性的setter,getter,在数 ...

  7. Vue 源码阅读(三)Special Attributes

    Special Attributes 包括以下:key ref slot v-* key https://vuejs.org/v2/api/#key The key special attribute ...

  8. Vue源码阅读(12):解析器

    今天聊聊解析器,解析器的作用是将程序员编写的模板字符串解析成抽象语法树,抽象语法树可以理解成模板字符串的对象表示形式,其本质并没有什么神奇的,只不过是 JS 中最为常见的对象字面量. 通过抽象语法树, ...

  9. for里面调用方法 vue_Vue源码阅读连载之Vue实例

    我们学习Vue都是从下面这个例子开始的 new Vue({render: h => h(App), }).$mount('#app') 事实上,所有的Vue项目的组成组件都是一个Vue的实例,最 ...

最新文章

  1. 如何用python画圆形的代码-简单实现python画圆功能
  2. java接口示例_【基础篇】java-接口及其示例
  3. HBase 2.0 之修复工具 HBCK2 运维指南
  4. 表单form数据默认以键值对的形式将数据回发到服务器,回发非纯文本需使用enctype=multipart/form-data方式编码为整条消息...
  5. 科学计算机看电量,解密:关于手机电量为1%是如何科学的算出来的?
  6. 其它数据类型和Json的转化
  7. 七步从Angular.JS菜鸟到专家(2):Scopes
  8. java新手笔记3 运算符循环
  9. java取当前日期_java如何获取系统的当前时间
  10. linux跳转乌班图服务器,Ubuntu18.04连接Linux服务器与文件传输
  11. day22 正则表达式 re
  12. kitkat(KRT16S)刷入实机nexus4
  13. Genymotion启动报错:VT-x/AMD-V硬件加速在您的系统中不可用
  14. kindeditor 加载 html,为kindeditor编辑器添加“引用”(blockquote)标签
  15. JAVA家教管理系统毕业设计 开题报告
  16. 王之泰201771010131《面向对象程序设计(java)》第七周学习总结
  17. Windows 7 安装软件错误:“Error 1935 ...HRESULT: 0x800736FD” 的解决办法
  18. 在tensorflow下进行pip操作时需要注意的地方
  19. 中兴echat_在追随用户的路上创新不止 — 中兴高达mini eChat解决方案
  20. 品•文案——聊聊产品文案优化设计

热门文章

  1. 宝宝安全座椅什么牌子好?[自己参考]
  2. [vb]SendMessageA函数
  3. 斯坦福大学2019年NLP课程上线,下周二开课 | 附PPT+视频
  4. 雷军振臂一呼:1亿小爱同学激活是不是中国第一?百度硬刚:我才是
  5. 再谈“炼金术”:可以使用不严谨的方法,但拒绝不严谨的评估方法
  6. 软件2.0时代来了!特斯拉AI负责人说:神经网络正在改变编程
  7. mapreduce中文乱码,已解决
  8. 排序算法与常见数据结构
  9. 高逼格又实用的Linux命令:持续更新中
  10. Higher level thinking