从 vue 源码看问题 — vue 如何进行异步更新?
前言
在上一篇 如何理解 vue 响应式? 中,了解到响应式其实是通过 Observer
类中调用 defineReactive() 即 Object.defineProperty()
方法为每个目标对象的 key(key 对应的 value 为非数组的)
设置 getter
和 setter
实现拦截,分别进行 依赖收集
和 依赖更新通知
,而 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 来完成异步执行
关于 Promise、MutationObserver、浏览器异步任务 等内容如果你还不算足够了解,那么在文末会给出的对应文章链接以提供大家去学习和深入了解.
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
数组并执行里面的回调函数
相关文章:

从 vue 源码看问题 — vue 如何进行异步更新?
前言 在上一篇 如何理解 vue 响应式? 中,了解到响应式其实是通过 Observer 类中调用 defineReactive() 即 Object.defineProperty() 方法为每个目标对象的 key(key 对应的 value 为非数组的) 设置 getter 和 setter 实现拦截&…...

【go从零单排】go中的基本数据类型和变量
Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 基本类型 go中的string、int、folat都可以用连接boolen可以用逻辑表达式计算 package mainimport "fmt&quo…...

标签之文字排版,图片,链接,音视频(HTML) 基础版
目录 标签之文字排版,图片,链接,音视频知识点: 练习题一: 效果: 练习题二: 效果: 标签之文字排版,图片,链接,音视频知识点: 超文本:链接 标记:标签<> 双标签 单标签 <br>//换行 <hr>//水平线 向后tab 向前shifttab html注释<!----> css /**/ …...

基于SpringBoot+Gpt个人健康管家管理系统【提供源码+答辩PPT+参考文档+项目部署】
作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…...

十四届蓝桥杯STEMA考试Python真题试卷第二套第一题
来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第一题 题目描述: 给定一个字符串,输出字符串中最后一个字符。 输入描述: 输入一个字符串 输出描述: 输出字符串中最后一个字符 样例输入: hgf 样…...

【Windows修改Docker Desktop(WSL2)内存分配大小】
记录一下遇到使用Docker Desktop占用内存居高不下的问题 自从使用了Docker Desktop,电脑基本每天都需要重启,内存完全不够用,从16g扩展到24,然后到40G,还是不够用;打开Docker Desktop 运行时间一长&#x…...

阿里云-部署CNI flannel集群网络
环境 1.一台阿里云作为k8s-master:8.130.XXX.231(阿里云私有IP) 2.Vmware 两个虚拟机分别作为 k8s-node1:192.168.40.131 k8s-node2:192.168.40.131 3.安装Docker 部署过程 k8s-master,k8s-node1,k8s-node2 初始操作 # 关闭防火墙 systemctl stop fi…...

favicon是什么文件?如何制作网站ico图标?
一般我们做网站的话,都会制作一个独特的ico图标,命名为favicon.ico。这个ico图标一般会出现在浏览器网页标题前面。如下图红色箭头所示: 部分博客导航大全也会用到所收录网站的ico图标。比如boke123导航新收录的网站就不再使用网站首页缩略图…...

Linux云计算个人学习总结(一)
windows计算机基础 一、概述 1.计算机基本原则:计算机是执行输入、运算、输出的原则。软件是指命令和数据的结合,计算机中所有的内容皆为数字。 2.计算机的类型 计算器 手机 cps等都属于计算机。 3.计算机的发展 第一代计算机电子管时代&…...

DCRNN解读(论文+代码)
一、引言 作者首先提出:空间结构是非欧几里得且有方向性的,未来的交通速度受下游交通影响大于上游交通。虽然卷积神经网络(CNN)在部分研究中用于建模空间相关性,但其主要适用于欧几里得空间(例如二维图像&a…...

雷池社区版新版本功能防绕过人机验证解析
前两天,2024.10.31,雷池社区版更新7.1版本,其中有一个功能,新增请求防重放 更新记录:hhttps://docs.waf-ce.chaitin.cn/zh/%E7%89%88%E6%9C%AC%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95 仔细研究了这个需求,…...

一文详解开源ETL工具Kettle!
一、Kettle 是什么 Kettle 是一款开源的 ETL(Extract - Transform - Load)工具,用于数据抽取、转换和加载。它提供了一个可视化的设计环境,允许用户通过简单的拖拽和配置操作来构建复杂的数据处理工作流,能够处理各种数…...

《IMM交互式多模型滤波MATLAB实践》专栏目录,持续更新……
专栏链接:https://blog.csdn.net/callmeup/category_12816762.html 专栏介绍 关于IMM的例程 双模型EKF: 【逐行注释】基于CV/CT模型的IMM|MATLAB程序|源代码复制后即可运行,无需下载三模型EKF: 【matlab代码】3个模型的IMM例程&…...

解决数据集中xml文件类别标签的首字母大小写不一致问题
import os import xml.etree.ElementTree as ET# 指定要处理的 XML 文件夹路径 xml_folder_path rD:\CVproject\ultralytics-main\datatrans\Annotationsdef capitalize_first_letter_in_xml(xml_file):# 解析 XML 文件tree ET.parse(xml_file)root tree.getroot()# 遍历所有…...

手边酒店多商户版V2源码独立部署_博纳软云
新版采用laraveluniapp开发,为更多平台小程序开发提供坚实可靠的底层架构基础。后台UI全部重写,兼容手机端管理。 全新架构、会员卡、钟点房、商城、点餐、商户独立管理...

32位汇编——通用寄存器
通用寄存器 什么是寄存器呢? 计算机在三个地方可以存储数据,第一个是把数据存到CPU中,第二个把数据存到内存中,第三个把数据存到硬盘上。 那这个所谓的寄存器,就是CPU中用来存储数据的地方。那这个寄存器有多大呢&a…...

vue3项目中实现el-table分批渲染表格
开篇 因最近工作中遇到了无分页情景下页面因大数据量卡顿的问题,在分别考虑并尝试了懒加载、虚拟滚动、分批渲染等各个方法后,最后决定使用分批渲染来解决该问题。 代码实现 表格代码 <el-table :data"currTableData"borderstyle"wi…...

开源办公软件 ONLYOFFICE 深入探索
文章目录 引言1. ONLYOFFICE 创建的背景1. 1 ONLYOFFICE 项目启动1. 2 ONLYOFFICE 的发展历程 2. 核心功能介绍2. 1 桌面编辑器2. 1. 1 文档2. 1. 2 表格2. 1. 3 幻灯片 2. 2 协作空间2. 3 文档编辑器 - 本地部署版 3. 技术介绍4. 安装5. 优势与挑战6. 个人体验7. 强大但不止于…...

原生鸿蒙应用市场:开发者的新机遇与深度探索
文章目录 自动化检测前移:提升开发效率与质量的新利器数据服务:数据驱动的精细化运营助手测试服务:保障应用质量的关键环节应用加密:保护应用安全与权益的利器从开发到运营的全方位支持写在最后 2024年10月22日,华为在…...

MATLAB实现蝙蝠算法(BA)
MATLAB实现蝙蝠算法(BA) 1.算法介绍 蝙蝠算法(简称BA)是一种受微型蝙蝠回声定位机制启发的群体智能算法,由Xin-She Yang于2010年提出。这种算法模拟了微型蝙蝠通过向周围环境发出声音并监听回声来识别猎物、避开障碍物以及追踪巢穴的行为。…...

WPF使用Prism框架首页界面
1. 首先确保已经下载了NuGet包MaterialDesignThemes 2.我们通过包的项目URL可以跳转到Github上查看源码 3.找到首页所在的代码位置 4.将代码复制下来,删除掉自己不需要的东西,最终如下 <materialDesign:DialogHostDialogTheme"Inherit"Ide…...

Linux中的软硬链接文件详解
概述 在Linux文件系统中,软连接(Symbolic Link)和硬连接(Hard Link)是两种重要的文件链接方式。它们都可以创建指向相同文件内容的多个“链接”,但在实现方式和特性上有所不同。 1. 硬连接(Ha…...

「Mac畅玩鸿蒙与硬件18」鸿蒙UI组件篇8 - 高级动画效果与缓动控制
高级动画可以显著提升用户体验,为应用界面带来更流畅的视觉效果。本篇将深入介绍鸿蒙框架的高级动画,包括弹性动画、透明度渐变和旋转缩放组合动画等示例。 关键词 高级动画弹性缓动自动动画缓动曲线 一、Animation 组件的高级缓动曲线 缓动曲线&#…...

pgsql数据量大之后可能遇到的问题
当 PostgreSQL 数据量增大时,可能会遇到以下问题: 查询性能下降:随着数据量的增加,查询可能会变得缓慢,尤其是在没有适当索引的情况下。大量的数据意味着更多的行需要被扫描和过滤,这会显著增加查询执行时间…...

Android 解决MTK相机前摄镜像问题
很莫名其妙的,前摄默认镜像,原来是为了前摄拍字体正确显示,比如自拍,前摄拍摄的人像虽左右镜像了,但如果后面有字牌显示,字体会显示正常而不是翻转。但现在需求是满足普遍的前摄原生代码不带镜像修改&#…...

在 Oracle 数据库中,SERVICE_NAME 和 SERVICE_NAMES 有什么区别?
在 Oracle 数据库中,SERVICE_NAME 和 SERVICE_NAMES 是两个相关的但略有不同的概念。它们都用于标识数据库服务,但使用场景和作用有所不同。下面详细解释这两个概念的区别: SERVICE_NAME 1. 定义: SERVICE_NAME 是一个单一的、…...

【Maven】——基础入门,插件安装、配置和简单使用,Maven如何设置国内源
阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 引入: 一:Maven插件的安装 1:环境准备 2:创建项目 二…...

AIGC时代LaTeX排版的应用、技巧与未来展望
文章目录 一、LaTeX简介与基础设置二、常用特殊符号与公式排版三、图片与表格的插入与排版四、自动编号与交叉引用五、自定义命令与样式六、LaTeX在AIGC时代的应用与挑战七、LaTeX的未来展望《LaTeX 入门实战》内容简介作者简介目录前言/序言读者对象本书内容充分利用本书 在AI…...

二叉树的深搜
前言: 本章节更深入学习递归 计算布尔二叉树的值 思路: 1.函数头设计:dfs(root) 2.函数体:需要一个接收left 和 right 的值 并且根据root的值进行比较 3.递归出口:很明显 当为叶子节点的时候…...

JUC笔记之ReentrantLock
ReentrantLock 相对于synchronized它具备如下特点 可中断 可以设置超时时间 可以设置为公平锁 支持多个条件变量(多个wait set,不同于synchronized的wait set,ReentrantLock的wait set在同一条件下notify才能唤醒WATING状态的线程) 与synchronized一样,都支持可重入 …...