源码:

  1. const callbacks = []
  2. let pending = false
  3.  
  4. function flushCallbacks () {
  5. pending = false
  6. const copies = callbacks.slice(0)
  7. callbacks.length = 0
  8. for (let i = 0; i < copies.length; i++) {
  9. copies[i]()
  10. }
  11. }
  12. let timerFunc
  13. if (typeof Promise !== 'undefined' && isNative(Promise)) {
  14. const p = Promise.resolve()
  15. timerFunc = () => {
  16. p.then(flushCallbacks)
  17. if (isIOS) setTimeout(noop)
  18. }
  19. isUsingMicroTask = true
  20. } else if (!isIE && typeof MutationObserver !== 'undefined' && (
  21. isNative(MutationObserver) ||
  22. MutationObserver.toString() === '[object MutationObserverConstructor]'
  23. )) {
  24. let counter = 1
  25. const observer = new MutationObserver(flushCallbacks)
  26. const textNode = document.createTextNode(String(counter))
  27. observer.observe(textNode, {
  28. characterData: true
  29. })
  30. timerFunc = () => {
  31. counter = (counter + 1) % 2
  32. textNode.data = String(counter)
  33. }
  34. isUsingMicroTask = true
  35. } else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
  36. timerFunc = () => {
  37. setImmediate(flushCallbacks)
  38. }
  39. } else {
  40. timerFunc = () => {
  41. setTimeout(flushCallbacks, 0)
  42. }
  43. }
  44.  
  45. export function nextTick (cb?: Function, ctx?: Object) {
  46. let _resolve
  47. callbacks.push(() => {
  48. if (cb) {
  49. try {
  50. cb.call(ctx)
  51. } catch (e) {
  52. handleError(e, ctx, 'nextTick')
  53. }
  54. } else if (_resolve) {
  55. _resolve(ctx)
  56. }
  57. })
  58. if (!pending) {
  59. pending = true
  60. timerFunc()
  61. }
  62. if (!cb && typeof Promise !== 'undefined') {
  63. return new Promise(resolve => {
  64. _resolve = resolve
  65. })
  66. }
  67. }

  总体来说:就是先判断是否支持promise,如果支持promise。就通过Promise.resolve的方法,异步执行方法,如果不支持promise,就判断是否支持MutationObserver。如果支持,就通过MutationObserver(微异步)来异步执行方法,如果MutationObserver还不支持,就通过setTimeout来异步执行方法。

  MutaionObserver通过创建新的节点,调用timerFunc方法,改变MutationObserver监听的节点变化,从而触发异步方法执行。

vue.$nextTick实现原理的更多相关文章

  1. 全面解析Vue.nextTick实现原理

    vue中有一个较为特殊的API,nextTick.根据官方文档的解释,它可以在DOM更新完毕之后执行一个回调,用法如下: // 修改数据 vm.msg = 'Hello' // DOM 还没有更新 V ...

  2. Vue.nextTick 的原理和用途

    转载自https://segmentfault.com/a/1190000012861862 概览 官方文档说明: 用法: 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法 ...

  3. 总结了一下 Vue.nextTick() 的原理和用途

    对于 Vue.nextTick 方法,自己有些疑惑.在查询了各种资料后,总结了一下其原理和用途,如有错误,请不吝赐教. 概览 官方文档说明: 用法: 在下次 DOM 更新循环结束之后执行延迟回调.在修 ...

  4. 【转载】Vue.nextTick 的原理和用途

    对于 Vue.nextTick 方法,自己有些疑惑.在查询了各种资料后,总结了一下其原理和用途,如有错误,请不吝赐教. 概览 官方文档说明: 用法: 在下次 DOM 更新循环结束之后执行延迟回调.在修 ...

  5. 通俗易懂了解Vue中nextTick的内部实现原理

    1. 前言 nextTick 是 Vue 中的一个核心功能,在 Vue 内部实现中也经常用到 nextTick.在介绍 nextTick 实现原理之前,我们有必要先了解一下这个东西到底是什么,为什么要 ...

  6. Vue源码解析之nextTick

    Vue源码解析之nextTick 前言 nextTick是Vue的一个核心功能,在Vue内部实现中也经常用到nextTick.但是,很多新手不理解nextTick的原理,甚至不清楚nextTick的作 ...

  7. vue.js及项目实战[笔记]— 03 vue.js插件

    一. vue补充 1. 获取DOM元素 救命稻草,document.querySelector 在template中标示元素`ref = "xxx" 在要获取的时候,this.$r ...

  8. js异步梳理:1.从浏览器的多进程到JS的单线程,理解JS运行机制

    大家很早就知道JS是一门单线程的语言.但是也时不时的会看到进程这个词.首先简单区分下线程和进程的概念 1. 简单理解进程 - 进程是一个工厂,工厂有它的独立资源 - 工厂之间相互独立 - 线程是工厂中 ...

  9. 2019前端面试系列——Vue面试题

    Vue 双向绑定原理        mvvm 双向绑定,采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter.getter,在数 ...

随机推荐

  1. 发布日志 - kratos v2.0.4 版本发布

    V2.0.4 Release Release v2.0.4 · go-kratos/kratos (github.com) 新的功能 proto-gen-http 工具在生产代码时如果 POST/PU ...

  2. HashMap 为什么线程不安全?

    作者:developer http://cnblogs.com/developer_chan/p/10450908.html 我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,但是其线 ...

  3. springMVC学习总结(一) --springMVC搭建

    springMVC学习总结(一) --springMVC搭建 搭建项目 1.创建一个web项目,并在项目中的src文件夹下创建一个包com.myl.controller. 2.添加相应jar包 3.在 ...

  4. 各种插值法的python实现

    一维插值 插值不同于拟合.插值函数经过样本点,拟合函数一般基于最小二乘法尽量靠近所有样本点穿过.常见插值方法有拉格朗日插值法.分段插值法.样条插值法. 拉格朗日插值多项式:当节点数n较大时,拉格朗日插 ...

  5. python glob.glob()

    glob()函数可以将某目录下所有跟通配符模式相同的文件放到一个列表中,有了这个函数,我们再想生成所有文件的列表就不需要使用for循环遍历目录了,直接使用glob.glob(path+pattern) ...

  6. uni-app 登录Abp VNexe并获取Token

    uni.request方式登录abp关键代码如下,因abp获取token需要用formdata方式请求所以需要加上请求头 const baseUrl = 'http://127.0.0.1:44323 ...

  7. js-监听网络状态

    <script> // 监听网络状态 window.addEventListener("online", function(){ alert("网络连接了&q ...

  8. 洛谷P1449——后缀表达式(栈模拟)

    题目描述 所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级). 如:3*(5–2)+7对应 ...

  9. Nginx TP5环境配置

    Apache默认支持Pathinfo模式  Nginx不支持  需要手动配置  Apache默认支持Pathinfo模式  Nginx不支持  需要手动配置 server { #配置监听端口 list ...

  10. webpack4. 使用autoprefixer 无效

    解决办法: 在package.json文件中加上这个 "browserslist": [ "defaults", "not ie < 11&qu ...