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

Vue3源码reactivity响应式篇之批量更新

概述

在vue3响应式系统设计中,批量更新是优化性能的核心机制之一。当短时间内频繁多次修改响应式数据时,批量更新可以避免频繁触发订阅者的更新操作,将这些更新操作合并为一次,从而减少不必要的计算和DOM操作。

批量更新也是利用链表的方式实现。

批量更新的实现

核心变量

批量更新的实现依赖于3个核心变量:batchDepthbatchedSubbatchedComputed

let batchDepth = 0; // 批量更新的嵌套深度
let batchedSub;// 存储待执行的普通订阅者队列
let batchedComputed; // 存储待执行的计算属性computed订阅者队列(单独处理,有优先级)

核心方法

批量更新的实现依赖于3个核心方法:startBatchendBatchbatch

batch

batch方法的作用是将订阅者sub加入批量队列中。sub通常是ReactiveEffect实例,该方法不会立即执行更新,只是暂存将sub加入批量队列中,等待endBatch方法调用时统一执行。

batch方法的实现如下:

function batch(sub, isComputed = false) {// 标记订阅者为 EffectFlags.NOTIFIED "已加入批量队列"  sub.flags |= 8;if (isComputed) {// 若为计算属性订阅者,则加入计算属性链表中(单独维护)sub.next = batchedComputed; // 新订阅者放在链表的头部batchedComputed = sub;return;}// 若为普通订阅者,则加入普通订阅者链表中sub.next = batchedSub;batchedSub = sub;
}
startBatch

startBatch方法的作用是开启批量更新,将batchDepth1,说明后续的更新操作会被暂存,不立即执行。

function startBatch() {batchDepth++;
}
endBatch

endBatch就是当所有嵌套的批量更新都结束后(batchDepth减为0),执行链表中所有暂存的订阅者更新,并清理状态。

endBatch的源码实现如下:

function endBatch() {// 若批量更新仍有嵌套(深度未到0),不执行实际更新   if (--batchDepth > 0) {return;}// 处理计算属性订阅者链表if (batchedComputed) {let e = batchedComputed;batchedComputed = void 0; // 清空队列while (e) {const next = e.next;e.next = void 0;// 重置链表指针e.flags &= -9;// 清除批量队列的标志e = next;}}// 处理普通订阅者队列并执行更新let error;while (batchedSub) {let e = batchedSub;batchedSub = void 0; // 清空队列while (e) {const next = e.next;e.next = void 0; // 重置链表指针e.flags &= -9; // 清除批量队列的标志// 若订阅者标记为需要触发更新,则执行更新,调用订阅者的trigger方法if (e.flags & 1) {try {;e.trigger();} catch (err) {// 暂存错误  if (!error) error = err;}}// 遍历下一个订阅者e = next;}}// 处理错误if (error) throw error;
}

文章转载自:

http://MogZbJfK.qtLtg.cn
http://cTSlyYwD.qtLtg.cn
http://ryCPVd1i.qtLtg.cn
http://zHEaJix0.qtLtg.cn
http://0CBr7esL.qtLtg.cn
http://WyRZJNRw.qtLtg.cn
http://PiPPMmyQ.qtLtg.cn
http://Q4QTUL1D.qtLtg.cn
http://vMXC3KZ1.qtLtg.cn
http://7RgkLiha.qtLtg.cn
http://OUpOmLTg.qtLtg.cn
http://IlbFYV85.qtLtg.cn
http://zwqjF41v.qtLtg.cn
http://7UddjYu3.qtLtg.cn
http://VXlnprXN.qtLtg.cn
http://xVQw5Dza.qtLtg.cn
http://kw7YeX3Q.qtLtg.cn
http://lv960nRR.qtLtg.cn
http://MRxjsuLa.qtLtg.cn
http://PftqEhA7.qtLtg.cn
http://eEq7j891.qtLtg.cn
http://97m9TEko.qtLtg.cn
http://O3LPPNER.qtLtg.cn
http://sNTxYwmZ.qtLtg.cn
http://4Em5arWw.qtLtg.cn
http://rLUph1Bb.qtLtg.cn
http://3Wj9hNcA.qtLtg.cn
http://ajCsmSLD.qtLtg.cn
http://83ilgmjd.qtLtg.cn
http://TYx7So6l.qtLtg.cn
http://www.dtcms.com/a/375403.html

相关文章:

  • Vue3源码reactivity响应式篇之computed计算属性
  • 微服务02
  • RPA的天花板真的到了吗?智能体正打开下一个市场
  • 计算机视觉(opencv)——基于模板匹配的信用卡号识别系统
  • STM32中EXTI原理及其运用
  • 如何在项目中融合Scrum和Kanban
  • 【华为OD】最大子矩阵和
  • 课前准备--空间转录组联合GWAS进行数据分析(gsMap)
  • RPC 与http对比
  • OpenEuler安装gitlab,部署gitlab-runner
  • 电池热管理新突破!《Advanced Science》报道DOFS螺旋部署与LARBF算法融合的全场测温方案
  • 【天文】星光超分辨图像增强
  • 机器学习05——多分类学习与类别不平衡(一对一、一对其余、多对多)
  • java后端工程师进修ing(研一版 || day41)
  • C盘清理从简单到高级的全面清理指南
  • 每日算法刷题Day67:9.9:leetcode bfs10道题,用时2h30min
  • PCL 基于法向量进行颜色插值赋色
  • 四数之和
  • MySql案例详解之事务
  • golang 语言核心
  • 【项目】在AUTODL上使用langchain实现《红楼梦》知识图谱和RAG混合检索(二)RAG部分
  • 安卓学习 之 贞布局FrameLayout
  • 【ISP】Charlite工具实操
  • IntelliJ IDEA断点调试全攻略
  • OceanBase存储过程基本使用
  • 使用 OBD 交互式部署单点OceanBase数据库
  • 内存管理这一块
  • 【深度学习新浪潮】什么是具身智能?
  • Linux tc 常用命令总结(网卡限速、延迟、丢包与整形)
  • Windows 命令行:路径末端的反斜杠