从 vue 源码看问题 — vue 如何进行异步更新?

前言

在上一篇 如何理解 vue 响应式? 中,了解到响应式其实是通过 Observer 类中调用 defineReactive() 即 Object.defineProperty() 方法为每个目标对象的 key(key 对应的 value 为非数组的) 设置 gettersetter 实现拦截,分别进行 依赖收集依赖更新通知,而 vue 的异步更新就在 setter 中的 dep.notify() 之后进行开启.

深入源码

下面针对源码的解读内容都在源码对应截图的注释中,就不在进行单独描述.

dep.notify() 方法

在这里插入图片描述

watcher.update() 方法

在这里插入图片描述

queueWatcher() 方法

在这里插入图片描述

flushSchedulerQueue() 方法

在这里插入图片描述

watcher.run() 方法

在这里插入图片描述

watcher.get() 方法

在这里插入图片描述

nextTick() 方法

在这里插入图片描述

timerFunc() 方法

timerFunc() 其实就是利用了浏览器的异步任务队列去执行 flushCallbacks() 方法,这整个过程其实就是 优雅降级

  • 首先判断当前环境是否支持 Promise,如果支持,就用 Promise 来触发回调函数
  • 如果不支持 Promise 就判断是否支持 MutationObserver,通过观察文本节点发生变化,去触发执行异步回调函数
  • 如果不支持 MutationObserver 就判断是否支持 setImmediate,如果支持,就通过 setImmediate 来触发回调函数
  • 如果以上都不支持就只能用 setTimeout 来完成异步执行

关于 PromiseMutationObserver浏览器异步任务 等内容如果你还不算足够了解,那么在文末会给出的对应文章链接以提供大家去学习和深入了解.

在这里插入图片描述

flushCallbacks() 方法

flushCallbacks() 方法会去清空 callbacks 数组并执行所有在 nextTick() 中保存的函调函数.
在这里插入图片描述

总结

vue 中如何实现异步更新?

vue 中的异步更新机制主要是利用了 浏览器的异步任务队列 来实现的,首选 微任务队列,其次选 宏任务队列

当响应式数据发生更改后,会在 setter 中调用 dep.notify 方法,通知 dep 中收集的所有 watcher 执行更新,即调用 watcher.update 方法,这个方法会把当前 watcher 加入到全局的 watcher 队列 queue(其实就是数组)

然后通过 nextTick 方法把 刷新 watcher 队列的方法,即 flushSchedulerQueue() 添加到全局的 callbacks 数组当中。

如果当前浏览器的异步任务队列中 不存在 flushCallbacks 函数,就通过 timerFunc 方法使用异步去执行 flushCallbacks 方法,这个方法会把 callbacks 清空并执行里面所有 flushSchedulerQueue 函数。

如果当前浏览器的异步任务队列中 存在 flushCallbacks 函数,那么就会等待当前异步队列中的 flushCallbacks 函数执行完成后,在加入下一个 flushCallbacks 函数。

其中负责刷新 watcher 队列的 flushSchedulerQueue() 函数,就会执行 queue 队列中的每个 watcher.run() 方法,从而进入更新阶段,如:执行组件的更新函数 updateComponents 或执行用户 watch 回调。

vue 中的 nextTick 原理是什么?

Vue-nextTick 在官方文档解释中,是用于在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后立即使用这个方法,获取更新后的 DOM。

  • nextTick 中,会把接收的回调函数 cb 使用 try catch 进行包裹,目的是方便进行异常捕获,之后会把这个 cb 存入到 全局的 callbacks 数组中
  • 执行 timerFunc,通过浏览器的异步循环队列去执行 flushCallbacks 函数清空 callbacks 数组并执行里面的回调函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/884707.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROS(Robot Operating System)中,编写一个记录机器人速度并将其转换成轨迹

在ROS(Robot Operating System)中,编写一个记录机器人速度并将其转换成轨迹的类涉及到几个步骤。以下是一个简单的示例,展示了如何创建这样一个类,并将其放置在一个自定义的命名空间中。这个类将订阅机器人的速度信息&…

[NewStarCTF 2023 公开赛道]逃1

代码审计. 这段代码分为三部分:1.war函数,2.GetFlag类,3.GetFlag类对象的定义,waf过滤以及反序列化 . 很经典的的一道题,键值对逃逸,改变cmd的value,去获取flag. 而war就是我们的突破点&#xf…

分享几个可以免费使用AI的网站

1、ChatGPT 自从用上GPT后,我的工作效率直接翻倍啊,不仅任务完成得更快,质量也更高。现在,我有更多的时间来享受生活,工作之余也能愉快地“摸鱼”,嘎嘎香嘞~ ⭐⭐ 点击直达 ​ 还有AI绘画可以体验喔~ 大…

如何抓住重点,系统高效地学习数据结构和算法?

要抓住重点、系统高效地学习数据结构和算法,可以从以下几个方面入手: 一、明确学习目标 确定学习的深度和广度 根据自己的学习需求和职业规划,确定学习数据结构和算法的深度和广度。如果你是为了应对面试,可能需要重点学习常见的数据结构和算法,以及它们的时间复杂度和空…

lego-loam mapOptmization 源码注释(二)

看过了main函数&#xff0c;我们来看mapOptmization的正题&#xff1a; MO.run(); void run(){if (newLaserCloudCornerLast && std::abs(timeLaserCloudCornerLast - timeLaserOdometry) < 0.005 &&newLaserCloudSurfLast && std::abs(time…

【大数据学习 | kafka】producer之拦截器,序列化器与分区器

1. 自定义拦截器 interceptor是拦截器&#xff0c;可以拦截到发送到kafka中的数据进行二次处理&#xff0c;它是producer组成部分的第一个组件。 public static class MyInterceptor implements ProducerInterceptor<String,String>{Overridepublic ProducerRecord<…

基于Spring Boot的高校物品捐赠管理系统设计与实现,LW+源码+讲解

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装高校物品捐赠管理系统软件来发挥其高效地信息处理的作用&a…

推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案

在数字化转型的浪潮中&#xff0c;企业对于数据传输的需求日益增加&#xff0c;特别是在不同网络环境之间的文件共享和传输。为了满足这一需求&#xff0c;FileLink数据跨网摆渡系统应运而生&#xff0c;为企业提供了一种安全、高效的数据传输解决方案。 安全第一&#xff0c;保…

C++_day2

目录 1. 引用 reference&#xff08;重点&#xff09; 1.1 基础使用 1.2 特性 1.3 引用参数 2. C窄化&#xff08;了解&#xff09; 3. 输入&#xff08;熟悉&#xff09; 4. string 字符串类&#xff08;掌握&#xff09; 4.1 基础使用 4.2 取出元素 4.3 字符串与数字转换 5. …

服务器数据恢复—RAID5阵列硬盘坏道掉线导致存储不可用的数据恢复案例

服务器存储数据恢复环境&#xff1a; 一台EqualLogic存储中有一组由16块SAS硬盘组建的RAID5阵列。上层划分了4个卷&#xff0c;采用VMFS文件系统&#xff0c;存放虚拟机文件。 服务器存储故障&#xff1a; 存储RAID5阵列中磁盘出现故障&#xff0c;有2块硬盘对应的指示灯亮黄灯…

25国考照片处理器使用流程图解❗

1、打开“国家公务员局”网站&#xff0c;进入2025公务员专题&#xff0c;找到考生考务入口 2、点击下载地址 3、这几个下载链接都可以 4、下载压缩包 5、解压后先看“使用说明”&#xff0c;再找到“照片处理工具”双击。 6、双击后会进入这样的界面&#xff0c;点击&…

2024年云手机推荐榜单:高性能云手机推荐

无论是手游玩家、APP测试人员&#xff0c;还是数字营销工作者&#xff0c;云手机都为他们带来了极大的便利。本文将为大家推荐几款在市场上表现优异的云手机&#xff0c;希望这篇推荐指南可以帮助大家找到最适合自己的云手机&#xff01; 1. OgPhone云手机 OgPhone云手机是一款…

浅谈RPC的实现原理与RPC实战

浅谈RPC的实现原理与RPC实战 什么是RPC?RPC框架基本原理gRPC框架介绍Http/2ProtoBuf gRPC实战一、创建项目二、导入依赖三、编写proto文件编写服务端编写客户端 什么是RPC? RPC(Remote Procedore Call)&#xff0c;及远程过程调用&#xff0c;是一种在分布式系统中用于进程间…

JeecgBoot入门

最近在了解低代码平台&#xff0c;其中关注到gitee上开源项目JeecgBoot&#xff0c;JeecgBoot官方也有比较完整的入门教学文档&#xff0c;这里我们将耕者官方教程学习&#xff0c;并将其记录下来。 一、项目简介 JeecgBoot 是一款基于代码生成器的低代码开发平台拥有零代码能力…

探索开源语音识别的未来:高效利用先进的自动语音识别技术20241030

&#x1f680; 探索开源语音识别的未来&#xff1a;高效利用自动语音识别技术 &#x1f31f; 引言 在数字化时代&#xff0c;语音识别技术正在引领人机交互的新潮流&#xff0c;为各行业带来了颠覆性的改变。开源的自动语音识别&#xff08;ASR&#xff09;系统&#xff0c;如…

.eslintrc.js 的解释

如果您的项目中没有 .eslintrc.js 文件&#xff0c;您可以按以下步骤创建并配置 ESLint&#xff1a; 1. 创建 ESLint 配置文件 在您的项目根目录下创建一个新的文件&#xff0c;命名为 .eslintrc.js。 2. 配置 ESLint 规则 在 .eslintrc.js 文件中添加以下内容&#xff0c;…

【Centos】在 CentOS 9 上使用 Apache 搭建 PHP 8 教程

在 CentOS 9 上使用 Apache 搭建 PHP 8 教程 1. 更新系统 确保你的系统是最新的&#xff1a; sudo dnf update2. 安装 EPEL 和 Remi 仓库 安装 Remi 仓库以获取 PHP 8&#xff1a; sudo dnf install epel-release sudo dnf install https://rpms.remirepo.net/enterprise/…

如何应对Oracle SQL语句的数据去重问题,应该考虑哪几个方面?

引言 在数据管理和数据库设计中,数据去重是一个重要的课题。随着信息技术的快速发展,数据的产生速度和数量都在急剧增加,如何有效地管理和维护这些数据成为了一个亟待解决的问题。 数据去重不仅可以减少存储空间的占用,还可以提高数据查询的效率,确保数据的准确性和一致…

Java基础语法①Java特点+环境安装+IDEA使用

目录 1. Java的概念和用途 1.1 Java的概念和发展史 1.2 Java的重要性 1.3 Java的特点 2. Java环境 2.1 JVM 和 JDK 2.2 Java环境安装 2.3 安装IntelliJ IDEA并使用 2.4 IntelliJ IDEA常见快捷键 2.4.1 普通快捷键 2.4.2 调试快捷键 2.4.3 代码生成快捷键 本篇完 写…

鸿蒙ArkTS中的面向对象编程

ArkTS是TypeScriptS的超集&#xff0c;而TS又是JavaScript的超集&#xff0c;意味着有JavaScript编程基础、结合一些TypeScript的使用经验就可以很快上手ArkTS。 作为一门面向对象语言的学习&#xff0c;了解和掌握这门语言的面向对象&#xff08;封装、继承、多态&#xff09;…