videojs v10 源代码系列解读:10 · `DestroyMixin`:双重 rAF 延迟销毁

FPGA上的时间数字转换器(TDC):详细概述及FPGA开发 本文对基于FPGA的时间数字转换器(TDC)进行了详细的概述,并提供了一个简单的示例代码,展示了如何在FPGA上实现TDC功能。在本文中,我们将详细概述基于FPGA的TDC,并提供相应的源代码示例,以帮助读者理解和实现这一功能。需要注意的是,这只是一个简单的示例,实际的TDC设计可能需要更多的功能和优化,以满足特定的需求。读取和重置:最后,测量结果可以通过读取计数器的值来获取,并且在每次读取后需要将计数器重置为零,以便进行下一次测量。TDC的基本原理是测量信号的到达时间与参考时钟之间的时间差。 阅读详情

这是 element 包的最后一篇,讲 DestroyMixin。它在 ReactiveElement 之上加了「永久销毁」语义。最值得说的是它那个双重 requestAnimationFrame 的设计——乍看很怪,但理解之后你会觉得这是处理「DOM 重组 / 框架协调」误销毁的妙招。另外它还有个「镜像 Set」的小技巧,解决真私有字段无法枚举的问题。

先说问题:disconnect 不等于销毁

Web Components 有个很坑的特性:元素从 DOM 移除时触发 disconnectedCallback,但这不一定意味着元素真的不要了。

考虑几个场景:

  1. DOM 重组:父元素把子元素从一个位置挪到另一个位置。过程中子元素会先 disconnect 再 reconnect。
  2. 框架协调:React/Vue 在 diff 时可能短暂移除再插回元素。
  3. 条件渲染:元素被「暂时」移除,稍后可能重新挂载。

如果你在 disconnectedCallback 里直接销毁元素(释放资源、解绑事件、调 destroy),那场景 1 和 2 会误销毁——元素明明还要用,却被你干掉了。

v8 时代这个问题很头疼。v10 的 DestroyMixin 给了个干净利落的解法。

hostDestroyed:区分「断连」和「永久销毁」

先看 DestroyMixin 在协议层加了什么。types.ts:58-63 新增了一个 hostDestroyed?() 钩子,JSDoc 写得很清楚:

当宿主被永久销毁时调用。与 hostDisconnected 不同,这表示宿主不会重新连接——应该释放所有资源。

所以 controller 现在有两个不同的 teardown 时机:

  • hostDisconnected——元素从 DOM 移除。可能只是暂时的(会重新连接),不该在这里释放重资源。
  • hostDestroyed——元素永久不要了。在这里释放所有资源。

这个区分非常关键。store 的 StoreController 就利用了它:disconnect 时只解订阅(可恢复),destroy 时才真正释放 store(不可恢复)。

DestroyMixin 的核心:双重 rAF

destroy-mixin.ts:64-74 是最精华的部分:

disconnectedCallback(): void {
  super.disconnectedCallback();                             // L65 — 先触发 hostDisconnected
  if (!this.#destroyed && !this.hasAttribute('keep-alive')) {  // L67
    requestAnimationFrame(() => {                           // L68 — 第一次 rAF
      requestAnimationFrame(() => {                         // L69 — 第二次 rAF
        if (!this.isConnected) this.destroy();              // L70
      });
    });
  }
}

我第一次看到双重 rAF 的时候很疑惑:为什么要两次?一次不行吗?

想明白之后,发现这是处理「DOM 重组」的关键:

  • 第一个 rAF:在下一次绘制之前触发。
  • 第二个 rAF:在下一次绘制之后触发。

所以销毁会跳过完整的一帧。这意味着:如果元素被 DOM 重组(先 disconnect 立刻 reconnect),到 rAF 回调执行时 this.isConnected 已经变回 true,L70 的检查会跳过销毁。误销毁被避免了。

L70 的 if (!this.isConnected) this.destroy() 是重入保护——只在确实仍然断开时才销毁。

为什么不用 setTimeout(0)

有人可能问:用 setTimeout(() => ..., 0) 不也能延迟吗?区别在于语义。rAF 和浏览器绘制周期对齐,能保证「至少完整一帧」。setTimeout(0) 实际是最小 4ms,且和绘制不对齐,在快速 DOM 重组时可能不够稳。双 rAF 是前端处理这类「下一帧再确认」的标准模式。

keep-alive:完全禁用自动销毁

注意 L67 的第二个条件:!this.hasAttribute('keep-alive')。

如果元素有 keep-alive 属性,完全不调度自动销毁。用户必须手动调 destroy()。这适合你知道元素会被频繁移除/重新插入、不想让它被自动回收的场景。JSDoc(L18-20)明确说明了这个语义。

销毁流程:destroy → destroyCallback

destroy-mixin.ts:37-47:

destroy(): void {
  if (this.#destroyed) return;              // L39 — 幂等
  this.#destroyed = true;                   // L40
  this.destroyCallback();                   // L41
}

destroyCallback(): void {
  for (const c of this.#trackedControllers) c.hostDestroyed?.();  // L43-47
}

destroy() 幂等(L39),设标志后调 destroyCallback()。destroyCallback 默认实现是给所有追踪的 controller 广播 hostDestroyed。子类覆盖 destroyCallback 时应调 super.destroyCallback() 来释放自己的资源。

镜像 Set:解决真私有字段问题

这里有个我读的时候觉得「真讲究」的设计。destroyCallback 要给 controller 广播,但 ReactiveElement 的 #controllers 是真私有(#-names,08 篇提过)——DestroyMixin 作为 mixin 根本访问不到它。

怎么办?DestroyMixin 维护了自己的镜像 Set(destroy-mixin.ts:30-31):

#destroyed = false;
#trackedControllers = new Set<ReactiveController>();

然后重写 addController / removeController(L49-57):

addController(controller: ReactiveController): void {
  super.addController(controller);              // L50 — 调基类
  this.#trackedControllers.add(controller);     // L51 — 镜像
}

removeController(controller: ReactiveController): void {
  super.removeController(controller);           // L55 — 调基类
  this.#trackedControllers.delete(controller);  // L56 — 镜像
}

每次 add/remove 都同步更新镜像 Set。这样 destroyCallback(L43-47)就能遍历 #trackedControllers 找到所有 controller 来广播 hostDestroyed。

这是 JS mixin 模式的一个典型痛点:基类用真私有字段,mixin 无法直接读。镜像 Set 是个干净解法——虽然多一份内存,但保证 mixin 能拿到完整的 controller 列表。

两道 guard:防止销毁后还干活

DestroyMixin 还加了两个 guard,防止销毁后元素还在更新或重连。

guard performUpdate(L76-79):

protected performUpdate(): void {
  if (this.#destroyed) return;    // L77 — 销毁后不更新
  super.performUpdate();          // L78
}

因为基类对销毁一无所知,所以 mixin 在这里 gate。销毁后,任何挂起的更新(或销毁后 controller/属性触发的 requestUpdate)都成 no-op。

guard connectedCallback(L59-62):

connectedCallback(): void {
  if (this.#destroyed) return;    // L60 — 销毁后不再启用
  super.connectedCallback();      // L61
}

已销毁的元素即使被重新插入 DOM,也不会重新启用或重新广播 hostConnected。注意这和 rAF 的重连保护(L70,阻止销毁发生)是两回事——那个是「还没销毁时防止误销毁」,这个是「已经销毁后防止复活」。

一个完整场景串一遍

假设播放器控件在 React 里被条件渲染:

  1. React 渲染 <media-controls> → connectedCallback → enableUpdating(true) → 正常工作。
  2. 用户切到别的页面,React 卸载组件 → disconnectedCallback(L65)→ 触发 hostDisconnected(controller 解订阅,可恢复)→ L67 检查通过 → 排双重 rAF。
  3. 用户立刻切回来,React 重新挂载 → connectedCallback(L61)。此时第一次 rAF 还没触发。
  4. 双重 rAF 触发 → L70 检查 this.isConnected → true(已重连)→ 跳过销毁。✅ 元素幸存。
  5. 如果用户没切回来 → L70 检查 false → destroy() → 广播 hostDestroyed(controller 释放重资源)。✅ 正常销毁。

对比如果用 disconnectedCallback 直接销毁:步骤 2 就把元素销毁了,步骤 3 重连时元素已经废了。这就是双重 rAF 的价值。

小结

DestroyMixin 代码不长(84 行),但解决了 Web Components 一个很实际的痛点。

带走这几个点:

  1. 双重 rAF 防误销毁——跳过完整一帧再确认 isConnected,DOM 重组/框架协调时元素能幸存。
  2. keep-alive 完全禁用自动销毁——用户全权控制。
  3. 镜像 Set 解决真私有字段——mixin 靠自己的追踪集广播 hostDestroyed。
  4. hostDestroyed vs hostDisconnected——区分「永久销毁」和「临时断连」,controller 该在哪释放重资源。
  5. 两道 guard——销毁后既不更新也不复活。

至此 element 包讲完了。下一篇我们进入 @videojs/store——v10 的响应式状态基石,看看它的微任务批处理是怎么做的(和 element 的批处理是两套,但思想相通)。

【第1章>第8节】FNN模糊神经网络的理论学习与MATLAB仿真 模糊神经网络(FNN,Fuzzy Neural Network)是将模糊逻辑与神经网络相结合的一种智能算法,它融合了模糊逻辑善于处理不确定性和神经网络的自学习、自适应能力。 阅读详情

相关推荐

准静态电磁场

叠加法 缺点:对于连续分布的电荷,叠加法的计算比较困难 虚位移法 概念 广义坐标:确实系统中导体形状、尺寸与位置的一组独立几何量。 广义力:企图改变某一广义坐标的力。 功:广义力乘上由它引起的广义坐标的改变量。 公式 ...

qq_35912930的博客 1860

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 206

DIY T12烙铁头驱动难题:用几个电容二极管,搞定NMOS上管驱动(附Multisim仿真)

本文详细介绍了如何利用电荷泵电路解决DIY T12烙铁头驱动中的NMOS上管驱动难题。通过巧妙组合电容和二极管,构建低成本高效的升压电路,实现栅极高压驱动需求。文章包含具体电路设计、元件选型建议、实际搭建注意事项以及Multisim仿真验证,为电子爱好者提供了一套完整的解决方案。

weixin_33640562的博客 334

从一段视频到可漫游的 4D 有声场景:思路拆解与最小复现手记

只需一段手机视频,你就能生成可"走进去"的 4D 有声场景:转头时狗叫声方向随之变化,走近时声音更清晰。本文拆解 Video-to-4DAVScene 的核心思路,手把手带你用几十行 Python 搭出最小管线,把视频中的运动物体变成带空间位置的声源,并附上三个真实踩坑的排障经验,代码可直接跑。🎧

helloagent的博客 234

一、两电平IGBT整流器

电压源换流器(Voltage source converter,VSC)连接交流主网和直流电网,起到交直流网络连接、功率输送和电能变换的作用。采用电压控制手段可维持直流电压的稳定;或采用功率控制手段保证系统功率输出达到预期。VSC的三相电压平衡方程如式(1)所示:式中,igx和ugx分别表示主网三相电流与电压(x=a,b,c);ucx表示换流器VSC 交流输出电压;Rg表示交流主网等效电阻;Lg表示交流主网等效电感。

TUCHACHINA的博客 4159

避坑!!!Stata双重机器学习(DML)遇到的问题及解决方式

除了上述代码,我还在Anaconda Navigator图形界面来更新conda,更新过的小伙伴应该都知道,这个过程非常漫长,我大概经历了2-3天,在这个过程中电脑一直运行,但是很不幸,无论哪种方式,最终都没有更新到最新版本。安装成功之后,我抱着试一试的心态再次在stata18MP中运行,没有想到,这次竟然运行成功了!我之前一直用的是stata17MP版本,在运行DML的时候,代码一直出错,我以为是python路径没有设置好的原因,就各种在python上面下功夫,经过各种查找后,确定DML必须要在。

王樰沫 3847

本地化部署会议视频软件如何替换旧平台?账号迁移、历史数据与用户培训怎么安排?

账号先映射:身份与权限验证通过,再开放使用。资料分级处理:能查、能读、权限正确,比“全部搬完”更重要。切换可恢复:入口、增量数据和业务通知都要纳入回退方案。培训按岗位落地:让用户完成真实任务,而不是只听功能介绍。这套方法适合政企、集团及医疗等具有长期资料留存、多终端接入和业务集成需求的组织。小规模替换可以简化批次与流程,但不应省略权限验证、备份恢复和关键会议演练。

hz56789的博客 281

ubuntu20.4源码安装最新gcc(gcc V12.2)

Ubuntu20.4自带的gcc为V9.4.0的版本,老版本的gcc存在不支持新版本C语言规范,在配置、编译、安装应用软件或工具时,可能存在不能正确安装的问题。(比如:libpqxx-7.7.4在配置时要求c++17版本的支持,但gcc V9.4.0版本不支持c++17)。因此本文介绍ubuntu20.4的系统下载最新gcc12.2版本源码,并进行本地编译、安装。本节内容包括gcc12.2的必备库安装和gcc12.2安装两部分内容组成。

q544344318的博客 1万+

打字就能剪视频的AI工具

AI 会替代剪辑师吗?这个问题和“AI 会替代程序员吗”一样,问错了方向。会用 AI 工具的人,正在替代不会用的人。一个剪辑师用传统方式花三天做的宣传片,另一个人用 UniCut 一天做完,质量差不多,市场会选谁,答案很明显。工具的进化从来不是把专业的人淘汰掉,而是把专业的门槛拆掉。浏览器已经打开了,剩下的就是你愿不愿意试一下。体验地址:https://unicut.h5ds.com/开源仓库:https://github.com/mtsee/unicut。

d676015863的博客 157

【GameFramework框架内置模块】15、场景(Scene)

场景(Scene)模块,提供场景管理的功能,负责场景的加载、卸载、切换和管理。可以方便地管理不同场景之间的切换以及不同场景之间的信息传递。

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 1886

【WorkBuddy专栏39】零基础也能做小程序——WorkBuddy微信小程序开发完全指南

【WorkBuddy专栏39】零基础也能做小程序——WorkBuddy微信小程序开发完全指南

AI人人懂 3152

音频自动匹配歌词:本地音乐库元数据维护实践

实施顺序建议为:建立主库、统一命名、批量匹配、人工校验、权限分享、定期备份。工具选择上,SMB/WebDAV、Navidrome、Jellyfin 以及轻量文件管理服务各有适用场景,应结合访问方式、权限需求和维护成本评估。把文件组织好、把批量操作控制住、把备份习惯建立起来,歌词补全才能真正提升本地音乐库的可用性,而不是带来新的整理负担。音乐文件不常修改,但歌词、封面、播放列表和目录结构属于人工整理成果,丢失后恢复成本较高。更合理的顺序是:集中存放、统一命名、批量匹配、人工校验、权限管理、定期备份。

zxcvb153的博客 116

基于Transformer的股票市场多因子量化选股模型,深度解析:基于Transformer的股票市场多因子量化选股模型

传统多因子模型通常采用线性回归、岭回归或Lasso回归来估计因子权重,其核心假设是因子与未来收益之间存在线性关系。然而,现实中的股票市场具有典型的非线性、非平稳和高噪声特征。卷积神经网络(CNN)擅长提取局部特征,但难以捕捉全市场股票之间的全局依赖关系;循环神经网络(RNN)及其变体LSTM虽然能处理时间序列,但存在梯度消失问题且难以并行计算。Transformer的self-attention机制能够:直接建模任意两只股票之间的相关性动态计算因子权重而非静态线性组合。

YOLO 250

视频美颜sdk的API设计会影响开发效率吗?

视频美颜SDK不仅需要具备优秀的图像处理能力,API接口设计同样会影响软件开发效率。本文从接口调用、参数配置、版本兼容、开发文档以及业务扩展等多个角度,分析API设计对视频美颜SDK集成和后期维护的实际影响,为直播APP、视频社交平台等项目的SDK选型与技术开发提供参考。

wanyuekeji的博客 211

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

视频号数据怎么采?接入方式、字段范围与场景适配

视频号数据采集的技术难点不在“调哪个接口”,而在。官方API服务的是“经营与交易”闭环,返回的是直播记录、订单、售后等结构化实体,但播放完成率、互动明细、评论区内容这些内容分析赖以生存的字段,并不在官方接口的返回Schema里。这意味着任何技术方案的选择,本质上是。

城章科技 297

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

AI 礼盒开箱视频怎么做?让商品亮相更有仪式感

AI商品视频通过精细设计开箱动作与场景节奏,将礼盒从静态包装转化为沉浸式送礼体验。从暖光布景、情感化构图到手部停顿、商品细节特写,每一帧都传递“精致”与“珍视”。以珠宝礼盒为例,俯拍视角下,红色对开门展开如舞台揭幕,银色项链在深蓝夜空衬底中缓缓呈现,掌心承托、缓慢转动,强化视觉记忆。结尾平铺构图,礼盒与商品共存,情绪由期待落至静谧珍藏。全程无文字,靠画面叙事,实现仪式感与品牌调性的深度融合。

yunhhhhh的博客 115

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

本地化部署会议视频软件如何开展试点?试用范围、评估指标与推广步骤

试用范围覆盖真实差异,评估指标具有明确口径,推广过程具备放行和回退机制。对于政企、金融、医疗及信创项目,尤其要避免三个误区:把本地部署等同于合规,把演示并发等同于生产容量,把功能清单等同于可运维能力。如果正在准备试点,建议先整理一张“网络—终端—业务—故障”矩阵,再决定试用人数。

hz56789的博客 320

RN鸿蒙空间音频实战

示例仓库:https://atomgit.com/m0_37170006/react-native-ohos-spatial-audio 社区导引:框架源码与版本发布见 https://atomgit.com/CPF-RN/ohos_react_native/tree/0.84-main CPF-RN 鸿蒙社区:https://atomgit.com/CPF-rn。

buhuisuanfa的博客 2万+

通过 AIGC 生成视频何时才能告别“抽卡”!

如果视频的主体内容已经符合要求,只存在错误字幕或局部画面瑕疵时,重新生成不仅增加成本,还可能改变原本满意的部分。针对这类问题,WAND-EraseVibe+ 提供了视频擦除与画面重建能力。根据腾讯云披露的技术方案,该工具采用基于隐空间 Transformer 的生成式修复架构,先将视频画面编码为隐空间特征,在特征层推断并重建需要修复的区域,再解码为视频画面。白模前置、垂直场景调优和局部修复分别作用于不同环节,目的都是减少为了获得可用内容而付出的重复生成成本。

Enweitech Software Works 147

网页视频资源识别与本地化管理:从 HTTP 流媒体技术到完整的视频工作流

现代网页视频技术已经从简单的文件传输发展到分段传输、自适应码率和浏览器端媒体处理。这使视频播放体验不断改善,也让资源识别和本地管理变得更加复杂。对于技术人员而言,理解 HTTP、HLS、MPEG-DASH 和 MSE 的基本工作机制,有助于更准确地分析网页视频的传输过程。对于视频创作者和研究人员而言,建立从内容发现、资源识别到本地整理的完整工作流,可能比单纯寻找一个下载工具更有长期价值。

m0_68263549的博客 408

联犀 Go SIMD 实战:视频转码从 16.5ms 到 5.46ms

联犀Go视频转码实战:在352×288测试流中单帧单核CPU耗时从16.5ms到5.46ms,区分SIMD、代码及编码策略的综合收益。保留测试条件、压测结果与适用边界。

QQ603785348的博客 333

15. 调用ComfyUI生成视频!

在“导演大师”中,我们不仅支持导出分镜导演包并一键导入运行,还为用户提供了极高的自定义自由度。许多创作者希望结合自己精心调试的 MiniMax H3 工作流来生成视频,这当然是完全支持的。通常有两种操作方式:一种是手动复制,将分镜的资产与提示词手动粘贴至本地工作流中;另一种则是更为高效的自动化方案——直接在“导演大师”中调用 ComfyUI 工作流,实现一键生成。本文将重点介绍后者的配置与使用全流程,帮助你打通从分镜脚本到视频直出的自动化链路。

2601_95544990的博客 238

AI智能美妆如何适应不同面部特征?视频美颜SDK技术解析

AI智能美妆正在推动视频美颜技术向个性化方向发展。面对不同用户的脸型、眼型、唇形及肤色差异,视频美颜SDK如何通过人脸检测、关键点识别、动态追踪和实时渲染实现精准适配?本文从核心技术原理、不同面部特征的妆容适配方式,以及实际应用场景等方面展开解析,帮助开发者了解AI智能美妆的技术实现与发展趋势。

q1031691172的博客 357

面向强噪声工业场景的 KL‑2510 音频 DSP 模组设计与多场景落地分析

KL-2510是一款22×16mm邮票孔SMT封装音频模组,集成ADC/DAC、AI-ENC降噪(45–90dB)与AEC回声消除(100dB),支持USB免驱及模拟/PDM麦克风输入,具备4档硬件拾音增益,适配医疗、矿山、安防等复杂噪声场景。通过五类真实案例验证其在病房对讲、井下报警、门铃对讲等应用中的稳定性与易用性。重点提示:需接入AEC_IN参考信号、输出加分压电路、外设勿接3V3电源,避免烧毁。适用于空间紧凑、无算法团队的嵌入式项目,显著降低音频开发门槛。

R190_6589的博客 391

Gemini Omni 1.2 Flash发布:视频10秒变15秒、720p降价30%

发布日期:2026-11-06Gemini Omni 1.2 Flash是Google于2026年11月发布的视频生成模型,支持原生15秒视频、多轮对话编辑和更强的参考素材遵循。Google公告发布于北京时间11月6日凌晨,官网标注日期为11月5日。相比Omni 1.1,新版把最长片段从10秒延长至15秒,720p视频单价降至每秒0.07美元,降幅30%。这次更新还涉及生成之后的修改:换背景、调光线、替换产品,可以围绕同一条视频继续提出要求。

aidoudoulong的博客 410

实时互动、直播、点播:音视频SDK选型的技术逻辑

在远程办公、在线教育、文娱电商、政务民生等数字化业务中,音视频能力已经成为多数互联网应用的基础设施。行业内目前形成了实时互动、直播、点播三种主流业务形态,三者在技术架构、传输逻辑与技术指标上差异明显。对研发团队和技术决策者来说,先分清业务属于哪种形态,再据此匹配音视频SDK与传输方案,可以直接影响研发周期、开发成本和终端体验。本文拆解三类业务形态的技术特征、核心指标与选型逻辑,并补充相关的传输原理,供选型时参考。## 一、实时互动:低延迟双向交互的技术体系实时互动的本质,是在双方或多方之间建立低延迟、高稳定

YWamy的博客 146
上一篇: videojs v10 源代码系列解读:09 · 异步更新调度:Promise 门控的微任务批处理
下一篇: videojs v10 源代码系列解读:11 · `@videojs/store`:目标附加式响应状态
逻辑玩家
博客等级 码龄19年 75粉丝 108原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值