前言:

本文需要一定的事件循环相关知识,想了解事件循环的小伙伴可以看 这里。

本文要弄明白下面两件事:

  • $nextTick什么时候执行
  • vue中nextTick与$nextTick区别

1.查看源码中的$nextTick方法

Vue.prototype.$nextTick = function(fn) { return nextTick(fn, this)};

可以看到$nextTick调用的也是nextTick方法,只不过$nextTick默认绑定了this上下文,也就是Vue实例对象

2.下面查看nextTick方法

function nextTick(cb, ctx) { var _resolve; callbacks.push(function() {  if (cb) {   try {    cb.call(ctx);   } catch (e) {    handleError(e, ctx, 'nextTick');   }  } else if (_resolve) {   _resolve(ctx);  } }); if (!pending) {  pending = true;  timerFunc(); } // $flow-disable-line if (!cb && typeof Promise !== 'undefined') {  return new Promise(function(resolve) {   _resolve = resolve;  }) }}
  • callbacks 一个异步队列,传入的回调函数会被存储在这个数组内,等待时机执行
  • if (!cb && typeof Promise !== 'undefined') 如果没有回调方法,并且当前环境支持Promise,那么nextTick返回的是一个Promise对象

3.查看timerFunc方法

if (typeof Promise !== 'undefined' && isNative(Promise)) { var p = Promise.resolve(); timerFunc = function() {  p.then(flushCallbacks);  //ios的UIWebViews中,回调推送到微任务队列后不会立即刷新,通过添加空定时器来强制刷新微任务队列  if (isIOS) {   setTimeout(noop);  } }; isUsingMicroTask = true;} else if (!isIE && typeof MutationObserver !== 'undefined' && (  isNative(MutationObserver) ||  // PhantomJS and iOS 7.x  MutationObserver.toString() === '[object MutationObserverConstructor]' )) { //如果支持MutationObserver var counter = 1; var observer = new MutationObserver(flushCallbacks); var textNode = document.createTextNode(String(counter)); observer.observe(textNode, {  characterData: true }); timerFunc = function() {  counter = (counter + 1) % 2;  textNode.data = String(counter); }; isUsingMicroTask = true;} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { // but it is still a better choice than setTimeout. timerFunc = function() {  setImmediate(flushCallbacks); };} else { // Fallback to setTimeout. timerFunc = function() {  setTimeout(flushCallbacks, 0); };}

经过一系列的判断方法,用来判断当前执行环境到底支持哪种方法,可以看到最后timerFunc执行的都是flushCallbacks方法。

4.flushCallbacks方法

function flushCallbacks() { pending = false; var copies = callbacks.slice(0); callbacks.length = 0; for (var i = 0; i 

这个方法执行时,会将回调队列做一个浅拷贝,并且初始化这个队列,防止影响下次事件循环,接下来将浅拷贝后的数组进行循环并执行。

到这步,$nextTick方法就算执行完毕了。

总结:

nextTick与$nextTick方法基本一致,$nextTick方法默认绑定vue实例为上下文。nextTick上下文需要传入,若不传入则默认绑定为window。 $nextTick 方法执行时会判断当前执行环境是否支持Promise若支持则放入Promise.then()内,若不支持则判断是否支持MutationObserver,如果不支持的话则会判断是否支持setImmediate方法,否则的话会加入setTimeout中。

一次事件循环(event loop)的过程

宏任务 => 所有微任务 => ui渲染

其中 Promise.then以及MutationObserver为微任务,在当前事件循环执行。

setImmediate、setTimeout为宏任务,在下次事件循环执行。

下面代码为vue源码中的nextTick相关代码,我做了部分注释。

var isUsingMicroTask = false; //是否使用MutationObserver来触发回调函数执行,另作他用,可以在源码中搜索用到的地方,本文不做深究var callbacks = []; //存储回调函数var pending = false; //此次nextTick是否执行中的标记var timerFunc; //触发方法function noop(a, b, c) {} //空函数,ios用来强制刷新微任务队列//执行回调队列function flushCallbacks() { pending = false; //执行中标记置否 var copies = callbacks.slice(0); //浅拷贝回调 callbacks.length = 0; // 清空数组 for (var i = 0; i 

vue 判断一个数是否在数组中_高级前端进阶,vue如何实现$nextTick相关推荐

  1. 【LeetCode】陌陌面试-有序数组于其一个元素翻转后,判断一个数是否存在数组中,时间复杂度O(logn)

    1.有序数组,判断一个数是否存在于数组中,时间复杂度O(logn) 解题思路: 二分法,在有序数组中,提高时间复杂度的一个方法. 代码: def demo(nums, target):left,rig ...

  2. java判断输入值是否在数组_java判断特定值是否在数组中的方法

    java判断特定值是否在数组中的方法: 使用List:public static boolean useList(String[] arr, String targetValue) { return ...

  3. java数组元素的输入_java基础--键盘输入一个数,输出数组中指定元素

    java基础--键盘输入一个数,输出数组中指定元素 java基础--键盘输入一个数,输出数组中指定元素 package com.lcn.day05; import java.util.Scanner; ...

  4. 有十五个数按由大到小顺序存放在一个数组中_数据结构基础 (代码效率优化, 线性表, 栈, 队列, 数组,字符串,树和二叉树,哈希表)...

    作者:张人大 代码效率优化 复杂度 -- 一个关于输入数据量n的函数 时间复杂度 -- 昂贵 与代码的结构设计有着紧密关系 一个顺序结构的代码,时间复杂度是O(1), 即任务与算例个数 n 无关 空间 ...

  5. 有十五个数按由大到小顺序存放在一个数组中_「图形化编程」前导知识-数组(一)...

    今天我们来学习一个新的概念-数组.这节课将通过一个小程序讲解数组的基本概念-数组的长度和下标 定义 数组指的是有序元素的集合,数组中的每个元素具有相同的类型,按照顺序排列的形式组织在一起.我们可以把数 ...

  6. Jquery判断元素是否包含在数组中$.inArray()

    项目中经常会遇到判断一个元素是否包含在数组中,用Jquery的话很简单,代码如下: var memberIdArr = new Array();var win = art.dialog.open.or ...

  7. LeetCode 1150. 检查一个数是否在数组中占绝大多数(二分查找)

    文章目录 1. 题目 2. 解题 2.1 暴力 2.2 二分查找 1. 题目 给出一个按 非递减 顺序排列的数组 nums,和一个目标数值 target. 假如数组 nums 中绝大多数元素的数值都等 ...

  8. 【Java】判断某值是否在数组中,使用Arrays类

    package com.company;import java.util.*; public class Main {public static void main(String arg[]) {Sy ...

  9. esp8266接收到的数据如何存放到数组中_愉快地学Java语言:第七章 数组

    导读 本文适合Java入门,不太适合Java中高级软件工程师.本文以<Java程序设计基础篇>第10版为蓝本,采用不断提出问题,然后解答问题的方式来讲述.本篇文章只是这个系列中的一篇,如果 ...

最新文章

  1. Vue PDF文件预览vue-pdf
  2. 阿里感悟系列文章(存)
  3. Iris recognition papers in the top journals in 2017
  4. python实例31[解析buildlog]
  5. linux下 最常用基本命令
  6. Java中运用数组的四种排序方法_JAVA中运用数组的四种排序方法
  7. PostgreSQL实际场景的十大缺陷你知道吗?
  8. 华为P50 Pro外观基本确认:居中开孔全面屏,首发鸿蒙操作系统
  9. linux挂载时间3秒,linux基础学习(十一) 时间的同步 设备的挂载
  10. 安装linux环境及相关包方法
  11. 容器技术Docker K8s 40 Serverless Kubernetes(ASK)详解-阿里云弹性容器实例ECI产品概述
  12. 格而知之8:我所理解的Runtime(3)
  13. 管理账目的计算机软件有哪些,会计核算软件有哪些功能模块
  14. 机器学习系列(2)_数据分析之Kaggle电影TMDB5000
  15. Microsemi Libero使用技巧3——使用FlashPro单独下载程序
  16. html设置type选择器,css :first-of-type选择器实例讲解
  17. Kafka HW及Epoch
  18. 19.通证的分类(各种分类一览表)
  19. 订阅号和服务号有什么区别?哪种更好?企业该如何选择?
  20. 本周聚划算| 避免上班5分钟被开除 直降2000元企业办公实用利器一站全掌握

热门文章

  1. java murmurhash实现_一致性哈希算法与Java实现
  2. python数据库操作批量sql执行_利用Python如何批量修改数据库执行Sql文件
  3. Oracle11g新特性:在线操作功能增强-Oracle11g在线重定义功能对物化视图... (转载)
  4. nvarchar(max)和表扫描
  5. android上拉刷新下拉加载
  6. 广东中国科学院计算机网络信息中心,中国科学院
  7. ubuntu 安装php redis,ubuntu上安装php redis
  8. 阶段1 语言基础+高级_1-2 -面向对象和封装_11使用对象类型作为方法的返回值
  9. linux buffer/cache手动释放
  10. Win10 中将网页转换成pdf的简便方法