当前位置: 首页 > news >正文

Vue是如何实现nextTick的?

你好同学,我是沐爸,欢迎点赞、收藏和关注。个人知乎

Vue.js 的 nextTick 函数是一个非常重要的功能,它用于延迟执行代码块到下次 DOM 更新循环之后。这在 Vue.js 的异步更新队列机制中非常有用,尤其是在你需要基于更新后的 DOM 来执行某些操作时。

实现原理

Vue.js 的 nextTick 的实现原理主要依赖于 JavaScript 的事件循环和微任务(microtask)或宏任务(macrotask)队列。Vue 使用了一种叫做“异步更新队列”的技术来优化 DOM 的更新。当你修改 Vue 组件的数据时,Vue 不会立即更新 DOM,而是将这些更新任务放入一个队列中,并在同一个事件循环的“下次迭代”中执行它们。这样做的好处是可以批量处理多次数据变化,只进行一次 DOM 更新,从而提高性能。

nextTick 函数允许你指定一个回调函数,这个回调函数会在 DOM 更新完成后被调用。Vue2和Vue3的实现有所不同。

Vue2的实现

Vue2通过判断浏览器环境,选择最适合当前环境的异步任务执行方式,以确保回调函数能够尽快执行,从而提高应用的响应速度和性能。

  1. Promise(如果浏览器支持)
    Vue 会检查是否支持 Promise,并尝试使用 Promise.resolve().then() 来安排回调函数在微任务队列中执行。这是因为微任务会在当前执行栈清空后立即执行,但在宏任务(如 setTimeout)之前。
  2. MutationObserver
    如果 Promise 不可用,Vue 会尝试使用 MutationObserver。MutationObserver API 用于在 DOM 树发生变化时异步执行回调函数。Vue 会创建一个文本节点作为观察目标,并在回调函数中调用你的 nextTick 回调函数。然后,它会改变这个文本节点的某些内容来触发 MutationObserver 的回调。
  3. setImmediate
    如果以上两者都不可用,Vue 会尝试使用 setImmediate(这是一个比 setTimeout 更快的 API,但在大多数环境中不可用)。
  4. setTimeout
    作为最后的回退选项,Vue 会使用 setTimeout 来安排回调函数在宏任务队列中执行。这是所有选项中最慢的,因为它会在浏览器重绘和重排之后执行。

源码:

var timerFunc; // 定时器函数
if (typeof Promise !== 'undefined' && isNative(Promise)) {var p_1 = Promise.resolve();timerFunc = function () { // 1.使用Promise.then()p_1.then(flushCallbacks);if (isIOS)setTimeout(noop);};isUsingMicroTask = true;
} else if (!isIE &&typeof MutationObserver !== 'undefined' &&(isNative(MutationObserver) ||MutationObserver.toString() === '[object MutationObserverConstructor]')) {var counter_1 = 1;var observer = new MutationObserver(flushCallbacks);var textNode_1 = document.createTextNode(String(counter_1));observer.observe(textNode_1, {characterData: true});timerFunc = function () { // 2.使用MutationObservercounter_1 = (counter_1 + 1) % 2;textNode_1.data = String(counter_1);};isUsingMicroTask = true;
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {timerFunc = function () { // 3.使用setImmediatesetImmediate(flushCallbacks);};
} else {timerFunc = function () { // 4.使用setTimeoutsetTimeout(flushCallbacks, 0);};
}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-lineif (!cb && typeof Promise !== 'undefined') {return new Promise(function (resolve) {_resolve = resolve;});}
}

Vue3的实现

不知道是因为Promise的支持度高,还是Vue3不在兼容低版本的浏览器,Vue3直接使用了Promise.then()这个微任务来处理DOM更新后的回调。

源码:

const resolvedPromise = /* @__PURE__ */ Promise.resolve();
let currentFlushPromise = null;
function queueFlush() {if (!isFlushing && !isFlushPending) {isFlushPending = true;currentFlushPromise = resolvedPromise.then(flushJobs);}
}function nextTick(fn) {const p = currentFlushPromise || resolvedPromise;return fn ? p.then(this ? fn.bind(this) : fn) : p;
}

查看源码可知,Vue3没有再向Vue2那样判断浏览器环境来选择异步任务执行方式,而是直接采用了Promise.then()方法。

希望对你有所帮助,下期再见!

相关文章:

Vue是如何实现nextTick的?

你好同学,我是沐爸,欢迎点赞、收藏和关注。个人知乎 Vue.js 的 nextTick 函数是一个非常重要的功能,它用于延迟执行代码块到下次 DOM 更新循环之后。这在 Vue.js 的异步更新队列机制中非常有用,尤其是在你需要基于更新后的 DOM 来…...

rabbitmq镜像集群搭建

用到的ip地址 ip地址端口192.168.101.65(主)15672192.168.101.7515672192.168.101.8515672 安装erlang和rabbitmq 安装 安装三个包 yum install esl-erlang_23.0-1_centos_7_amd64.rpm -y yum install esl-erlang-compat-18.1-1.noarch.rpm -y rpm -…...

《c++并发编程实战》 笔记

《c并发编程实战》 笔记 1、你好,C的并发世界为什么要使用并发 第2章 线程管理2.1.1 启动线程2.2 向线程函数传递参数2.5 识别线程 第3章 线程间共享数据3.2.1 C中使用互斥量避免死锁的进阶指导保护共享数据的替代设施 第4章 同步并发操作4.1 等待一个事件或其他条件…...

57qi5rW35LqRZUhS pc.mob SQL注入漏洞复现

0x01 产品简介 57qi5rW35LqRZUhS是大中型企业广泛采用人力资源管理系统。某云是国内顶尖的HR软件供应商,是新一代eHR系统的领导者。 0x02 漏洞概述 57qi5rW35LqRZUhS pc.mob 接口存在SQL注入漏洞,未经身份验证的远程攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例…...

微信小程序--27(自定义组件4)

一、父子组件之间通信的3种方式 1、属性绑定 用于父组件向子组件的只当属性设置数据,但只能设置JSON兼容的数据 2、事件绑定 用于子组件向父组件传递数据,可以传递任意数据 3、获取组件实例 父组件还可以通过this.select Component()获取子组件的实…...

Linux | Linux进程万字全解:内核原理、进程状态转换、优先级调度策略与环境变量

目录 1、从计算机组成原理到冯诺依曼架构 计算机系统的组成 冯诺依曼体系 思考:为什么计算机不能直接设计为 输入设备-CPU运算-输出设备 的结构? 2、操作系统(Operator System) 概念 设计OS的目的 描述和组织被管理对象 3、进程 基本概念 进程id和父进程…...

VBA技术资料MF184:图片导入Word添加说明文字设置格式

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…...

在函数设计中应用单一职责原则:函数分解与职责分离

在函数设计中应用单一职责原则:函数分解与职责分离 引言 单一职责原则(Single Responsibility Principle, SRP)是面向对象设计原则中的核心原则之一,强调一个类或函数应该只有一个责任或理由去改变。在函数设计中,应…...

多线程锁机制面试

目录 乐观锁的底层原理 ReentrantLock的实现原理 读写锁 ReentrantReadWriteLock synchronized 底层原理 Lock和synchronized的区别 乐观锁的底层原理 版本号机制 在数据库表中添加一个版本号字段(如 version),每次更新数据时都会将版本号…...

《SQL 中计算地理坐标两点间距离的魔法》

在当今数字化的世界中,地理数据的处理和分析变得越来越重要。当我们面对一个包含地理坐标数据的表时,经常会遇到需要计算两点之间距离的需求。无论是在物流配送路线规划、地理信息系统应用,还是在基于位置的服务开发中,准确计算两…...

微服务可用性设计

一、隔离 对系统或资源进行分割,实现当系统发生故障时能限定传播范围和影响范围。进一步的,通过隔离能够降低系统之间得耦合度,使得系统更容易维护和扩展。某些业务场景下合理使用隔离技巧也能提高整个业务的性能。我理解隔离本质就是一种解…...

【扒代码】dave readme文档翻译

jerpelhan/DAVE (github.com) 摘要 低样本计数器估算选定类别对象的数量,即使在图像中只有少量或没有标注样本的情况下。目前最先进的技术通过对象位置密度图的总和来估算总数量,但这种方法无法提供单个对象的位置和大小,这对于许多应用来说…...

c语言---文件

这一节我准备分三个部分来带领大家了解文件 ——一、有关文件的基础知识 ————二、文件的简单操作 ————————三、文件结束的判定 ————————————四、文件缓冲区 一、文件的基础知识: 首先在了解文件之前,我们需要了解C/C程序内存…...

Windows系统下Go安装与使用

step1: 下载go语言SDK 下载地址:https://go.dev/dl/ 下载后选择合适位置安装即可,我选择D盘 在安装完成后,可以通过go env 命令检测是否安装成功。在“命令提示符”界面输入“go env”命令,如果显示如下类似结果则说明…...

day24-测试之接口测试基础

目录 一、接口的定义 二、接口的优点 三、API接口 四、接口测试流程 五、网络基础概念 六、HTTP和RURL 七、get和post请求 八、数据格式 九、状态码 十、restful风格 十一、接口工具 一、接口的定义 程序之间协作所要遵循的一套规范、标准 二、接口的优点 2.1.责任…...

TSN 交换机

TSN(Time-Sensitive Networking)交换机是一种支持时间敏感网络协议的网络交换设备,用于在以太网网络中实现低延迟、高确定性的数据传输。TSN 是一组 IEEE 802 标准的集合,旨在通过标准化的方式,将传统的以太网扩展到需…...

针对thinkphp站点的漏洞挖掘和经验分享

0x1 前言 浅谈 目前在学习和研究thinkphp相关漏洞的打法,然后最近对于thinkphp资产的收集方面有了一个简单的认识,然后写一篇新手看的thinkphp相关的漏洞收集和挖掘的文章来分享下。然后后面是给师傅们分享下后台文件上传,然后直接打一个ge…...

MySQL数据库入门,pycharm连接数据库—详细讲解

一.安装MySQL 1.常用MySQL5.7,首先安装MySQL, (一) (二) (三) (四) (五) 2.配置环境变量 打开MySQL安装路径,在其中找到…...

.bat文件快速运行vue项目

如何使用bat文件快速运行vue项目? 新建个文件,改名为serve.bat。 在文件中写入以下内容: # cd 项目路径 cd D:\projects\xxx npm run serve pausecd 项目所在的路径 npm run dev/serve ,取决于项目的启动方法,打…...

数据结构(邓俊辉)学习笔记】优先级队列 07——堆排序

1.算法 作为完全二叉堆的一个应用,这节来介绍堆排序算法。 是的,谈到优先级队列,我们很自然地就会联想到排序。因为就其功能而言,包括完全二叉堆在内的任何一种优先级队列都天生地具有选取功能,也就是选取其中的最大…...

自媒体人的秘密武器:OpenClaw+Qwen3-32B-Chat全平台内容分发

自媒体人的秘密武器:OpenClawQwen3-32B-Chat全平台内容分发 1. 为什么我需要一个自动化内容分发助手 去年夏天,我同时运营着公众号、微博和短视频三个平台。每次创作完核心内容后,总要花大量时间做格式转换:把长文章拆成微博线程…...

Spring Cloud Hystrix 详细示-元一软件

Hystrix 是 Spring Cloud 中实现服务熔断、降级、隔离的核心组件,用于解决微服务架构中的雪崩效应,核心是快速失败、优雅降级、自动恢复。以下从环境搭建、基础使用、高级配置、Feign 整合、监控5 个维度提供完整示例。一、项目环境准备1. 依赖引入&…...

如何快速掌握B站视频下载:DownKyi面向新手的终极教程

如何快速掌握B站视频下载:DownKyi面向新手的终极教程 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等&#x…...

C语言开发环境哪家强?VSCode优势多,配置步骤快来看

当前存在多种C语言开发环境,其中最为专业的当属CLion,它能够运用各类AI辅助编程插件,然而无法免费使用,并且体积过于庞大。免费的像DevCpp等,体积较小,配置简便,只是无法接入AI辅助编程插件。VS…...

OneButton库详解:嵌入式单按键多态交互设计与实现

1. OneButton 库深度解析:面向嵌入式系统的单按钮多态交互设计与工程实现1.1 库定位与工程价值OneButton 是一个轻量级、无依赖的 Arduino 兼容库,专为解决嵌入式系统中单物理按键承载多重用户意图这一经典工程难题而设计。在资源受限的 MCU(…...

从OBS源码看WASAPI实战:Windows音频采集的‘静音循环’修复与高精度时间戳处理

从OBS源码剖析WASAPI音频采集:静音循环修复与高精度时间戳的工程实践 在直播软件OBS的音频处理模块中,WASAPI接口的高效运用直接决定了音画同步质量与系统资源占用率。本文将深入OBS源码,揭示其解决Windows音频采集两大核心难题的技术方案&am…...

FOSUserBundle配置参考:所有参数详解与最佳配置方案

FOSUserBundle配置参考:所有参数详解与最佳配置方案 【免费下载链接】FOSUserBundle Provides user management for your Symfony project. Compatible with Doctrine ORM & ODM, and custom storages. 项目地址: https://gitcode.com/gh_mirrors/fo/FOSUserB…...

终极指南:SimpleNES如何通过数学魔法还原经典NES音效

终极指南:SimpleNES如何通过数学魔法还原经典NES音效 【免费下载链接】SimpleNES An NES emulator in C 项目地址: https://gitcode.com/gh_mirrors/si/SimpleNES SimpleNES是一款用C编写的NES模拟器,它不仅能精确模拟NES游戏机的图形显示&#x…...

国密SM4算法在Web与Java应用中的跨平台加解密实战

1. 国密SM4算法简介与应用场景 国密SM4算法是我国自主设计的分组对称加密算法,于2012年成为国家密码行业标准(GM/T 0002-2012)。作为替换国际算法(如AES)的重要选择,SM4在金融、政务、物联网等领域得到广泛…...

Qwen3.5-4B-Claude-Opus惊艳效果展示:分步骤推导二分查找O(log n)全过程

Qwen3.5-4B-Claude-Opus惊艳效果展示:分步骤推导二分查找O(log n)全过程 1. 模型能力概览 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是一个专为推理任务优化的轻量级模型,特别擅长处理需要分步骤分析的技术问题。这个4B参数的模型通过蒸馏…...