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

React18源码: schedule任务调度messageChannel

React调度原理(scheduler)

  • 在React运行时中,调度中心(位于scheduler包)
  • 是整个React运行时的中枢(其实是心脏),所以理解了scheduler调度,就基本掌握了React的核心
  • React两大循环:从宏观的角度介绍 React 体系中两个重要的循环,其中任务调度循环就是本文的主角
  • Reconciler 运行流程从宏观的角度描述了 react-reconciler 包的核心作用
    • 并把 reconciler 分为了4个阶段
    • 其中第 2 个阶段注册调度任务串联了 scheduler 包和 react-reconciler 包
    • 其实就是任务调度循环中的一个任务(task)
  • 优先级管理
    • React体系中的3中优先级的管理
    • 着重源码中react-reconciler与scheduler包中关于优先级的转换思路
    • 其中 SchedulerPriority 控制任务调度循环中循环的顺序

调度实现

调度中心最核心的代码,在 SchedulerHostConfig.default.js 中

内核

  • 该js文件一共导出了8个函数,最核心的逻辑,就集中在了这8个函数中
    export let requestHostCallback; // 请求及时回调: port.postMessage
    export let cancelHostCallback; // 取消及时回调: scheduledHostCallback = null
    export let requestHostTimeout; // 请求延时回调: setTimeout
    export let cancelHostTimeout; // 取消延时回调: cancelTimeout
    export let shouldYieldToHost; // 是否让出主线程 (currentTime >- deadline && needsPaint):
    export let requestPaint; // 请求绘:设置 needsPaint = true
    export let getCurrentTime; // 获取当前间
    export let forceFrameRate; // 强制设置 yieldIntervol (让出主线程的周期)
    
  • react可以在nodejs环境中使用,所以在不同的js执行环境中,这些函数的实现会有区别
  • 下面基于普通浏览器环境,对这8个函数逐一分析

1 )调度相关:请求或取消调度

  • requestHostCallback

  • cancelHostCallback

  • requestHostTimeout

  • cancelHostTimeout

  • 这4个函数源码很简洁,非常好理解,它们的目的就是请求执行(或取消)回调函数

  • 现在重点介绍其中的及时回调 (延时回调的2个函数暂时属于保留api,17.0.2版本其实没有用上)

    // MessageChannel
    const performWorkUntilDeadline=() => {//...省略无关代码if (scheduledHostCallback !== null) {const currentTime = getCurrentTime();// 更新 deadlinedeadline = currentTime + yieldInterval;// 执行 callbackscheduledHostCallback(hasTimeRemaining, currentTime);} else {isMessageLoopRunning = false;};
    };const channel = new MessageChannel();
    const port = channel.port2;
    channel.port1.onmessage = performWorkUntilDeadline;// 请求回调
    requestHostCallback = function(callback) {// 1.保存callbackscheduledHostCallback = callback;if(!isMessageLoopRunning) {isMessageLoopRunning= true;// 2.通过 MessageChannel消息port.postMessage(null);}
    };// 取消回调
    cancelHostCallback = function() {scheduledHostCallback = null;
    }
    
  • 很明显,请求回调之后 scheduledHostCallback = callback

  • 然后通过MessageChannel发消息的方式触发performWorkUntilDeadline函数

  • 最后执行回调 scheduledHostCallback

  • 此处需要注意

    • MessageChannel在浏览器事件循环中属于宏任务
    • 所以调度中心永远是异步执行回调函数

2 )时间切片(timeslicing)相关:

  • 执行时间分割,让出主线程

  • 把控制权归还浏览器,浏览器可以处理用户输入,UI绘制等紧急任务

  • getCurrentTime: 获取当前时间

  • shouldYieldToHost: 是否让出主线程

  • requestPaint: 请求绘制

  • forceFrameRate: 强制设置yieldInterval(从源码中的引用来看,算一个保留函数,其他地方没有用到)

    const localPerformance = performance;
    // 获取当前时间
    getCurrentTime = () => localPerformance.now();// 时间切片周期,默认是5ms(如果一个task运行超过该周期,下一个task执行之前,会把控制权归还浏览器)
    let yieldInterval = 5;
    let deadline = 0;
    const maxYieldInterval = 300;
    let needsPaint = false;
    const scheduling = navigator.scheduling;
    // 是否让出主线程
    shouldYieldToHost = function() {const currentTime = getCurrentTime();if (currentTime >= deadline) {if (needsPaint || scheduling.isInputPending()) {// There is either a pending paint or a pending input.return true;}// There's no pending input. Only yield if we've reached the max// yield interval.return currentTime >= maxYieldInterval; // 在持续运行的react应用中, currentTime肯定大于300ms} else {// There's still time left in the frame.return false;}
    };// 请求绘制
    requestPaint = function() {needsPaint = true;
    };// 设置时间切片的周期
    forceFrameRate = function(fps) {if (fps < 0 || fps > 125) {// Using console['error'] to evade Babel and ESLintconsole['error']('forceFrameRate takes a positive int between 0 and 125, ' +'forcing frame rates higher than 125 fps is not supported',);return;}if (fps > 0) {yieldInterval = Math.floor(1000 / fps);} else {// reset the framerateyieldInterval = 5;};
    }
    
  • 这4个函数代码都很简洁,其功能在注释中都有解释.

  • 注意 shouldYieldToHost 的判定条件:

    • currentTime >= deadline: 只有时间超过 deadline 之后才会让出主线程
    • 其中 deadline = currentTime + yieldInterval
      • yieldInterval 默认是5ms, 只能通过 forceFrameRate 函数来修改
      • 如果一个task运行时间超过5ms,下一个task执行之前,会把控制权归还浏览器
  • navigator.scheduling.isInputPending():

    • 这facebook官方贡献给 Chromium 的api,现在已经列入W3C标准
    • 用于判断是否有输入事件(包括:input框输入事件,点击事件等).
  • 看完这8个内部函数,最后浏览一下完整的 performWorkUntilDeadline 回调的实现

    const performWorkUntilDeadline = () => {if(scheduledHostCallback !== null) {const currentTime = getCurrentTime(); //1.获取当前时间deadline = currentTime + yieldInterval; //2.  置deadline 当前时间 + 5ms, 也就是5ms超时const hasTimeRemaining = true;try {//  3.执行回调,返回是否有还有剩余任务const hasMoreWork = scheduledHostCallback(hasTimeRemaining, currentTime);if (!hasMoreWork) {// 没有剩余任务,退出isMessageLoopRunning = false;scheduledHostCallback = null;} else {port.postMessage(null); // 有剩余任务,发起新的调度}} catch (error) {port.postMessage(null); // 如有异常,重新发起调度throw error;}} else {isMessageLoopRunning = false;}needsPaint = false; // 重置开关
    }
    
  • 核心总结,如下图

  • MessageChanel 里面是宏任务异步执行
  • 在执行的过程中,基于 performWorkUnitlDeadline
  • 这个方法在执行任务过程中,有一个变量 hasMoreWork
  • 基于这个变量判断是否还有任务,如果还有,则继续往里面注册回调,没有则退出

相关文章:

React18源码: schedule任务调度messageChannel

React调度原理(scheduler) 在React运行时中&#xff0c;调度中心&#xff08;位于scheduler包&#xff09;是整个React运行时的中枢&#xff08;其实是心脏&#xff09;&#xff0c;所以理解了scheduler调度&#xff0c;就基本掌握了React的核心React两大循环&#xff1a;从宏…...

Jmeter 学习目录

Jmeter 所有内容均以学习为主输出内容&#xff0c;按照最小单位和基础进行输出。 如果有看不懂&#xff0c;或者有不明确的内容&#xff0c;欢迎大家留言说明。 Jmeter系列&#xff08;1&#xff09;Mac Jmeter下载安装启动 Jmeter系列&#xff08;2&#xff09;Jmeter 目录介…...

计算机网络 数据链路层课后题

1.以太网帧有哪些不同的封装格式&#xff1f;他们有何区别和应用场景&#xff1f; 以太网II封装&#xff08;Ethernet II&#xff09;&#xff1a;以太网II封装是最常用的以太网封装格式&#xff0c;也被称为DIX封装。它在数据链路层首部使用6个字节的目的MAC地址和6个字节的源…...

实现验证码功能

Kaptcha 文章目录 Kaptcha介绍插件使用介绍原理引入依赖生成验证码 验证码小项目初始化前端代码约定前后端交互接口接口定义 介绍 Kaptcha 是Google的⼀个⾼度可配置的实⽤验证码⽣成⼯具 https://code.google.com/archive/p/kaptcha ⽹上有很多⼈甚⾄公司基于Google的kaptc…...

PyQt6的开发流程(密码生成小程序为例)

PyQt6的开发流程&#xff08;密码生成小程序为例&#xff09; 文章目录 PyQt6的开发流程&#xff08;密码生成小程序为例&#xff09;一、流程介绍与概览1. 界面与逻辑分离的开发流程2. PyQt6的开发流程 二、打开 designer.exe 创建文件三、用QT设计师绘制界面保存成ui1. QT常用…...

思腾云计算中心 | 5千平米超大空间,基础设施完善,提供裸金属GPU算力租赁业务

2021年&#xff0c;思腾合力全资收购包头市易慧信息科技有限公司&#xff0c;正式开启云计算业务。思腾云计算中心占地2400平米&#xff0c;位于包头市稀土高新区&#xff0c;毗邻多家知名企业&#xff0c;地理位置优越&#xff0c;交通便利&#xff0c;是区内重要的信息化产业…...

【Leetcode每日一题】二分查找 - 在排序数组中查找元素的第一个和最后一个位置(难度⭐⭐)(18)

1. 题目解析 Leetcode链接&#xff1a;34. 在排序数组中查找元素的第一个和最后一个位置 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于找到给定目标值所在的数组下标区间&#xff0c;设计一个O(logn)的算法。 2. 算法原…...

远程连接 vscode 出错 “远程主机可能不符合 glibc 和 libstdc++ VS Code 服务器的先决条件”

原因&#xff1a; vscode 版本是 1.86&#xff0c;服务器上的 glibc 和 libstdc 版本不满足 要求(2.28 和 3.4.25)。 解决&#xff1a; 1、下载 1.85.2&#xff0c;解压直接运行 Code.exe。 2、回退 Remote-ssh 到 0.107.1。 参考&#xff1a; vscode 1.86版本远程ssh不兼容旧…...

Maven入门:Java项目构建和管理的利器

Maven入门&#xff1a;Java项目构建和管理的利器 Maven 是一个项目管理和综合工具&#xff0c;它基于项目对象模型&#xff08;POM&#xff09;概念。Maven 可以管理项目的构建、报告和文档。以下是一篇介绍 Maven 配置和应用的教程文章。 Maven简介 Maven 使用其核心概念 POM…...

《游戏引擎架构》 -- 学习4

资源及文件系统 文件系统 游戏引擎的文件系统API通常提供以下功能&#xff1a; 搜需路径&#xff1a;是含一串路径的字符串&#xff0c;各路径之间以特殊字符&#xff08;如冒号或分号&#xff09;分隔&#xff0c;找文件时就会从这些路径进行搜寻。例如在命令行下执行程序&a…...

Wagtail安装运行并结合内网穿透实现公网访问本地网站界面

文章目录 前言1. 安装并运行Wagtail1.1 创建并激活虚拟环境 2. 安装cpolar内网穿透工具3. 实现Wagtail公网访问4. 固定的Wagtail公网地址 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xf…...

10分钟快速开始SkyWalking结合Springboot项目

10分钟快速开始SkyWalking结合Springboot项目 实习期间&#xff0c;公司让我去学习一下链路追踪如何集成到Springboot项目中。 为此有两个方案&#xff1a; 1.opentelementryjaegerprometheus opentelementry 收集器收集线上的metrics和traces&#xff0c;然后发送给jaeger和p…...

STM32—触摸键

目录 1 、 电路构成及原理图 2 、编写实现代码 3、代码讲解 4、烧录到开发板调试、验证代码 5、检验效果 此笔记基于朗峰 STM32F103 系列全集成开发板的记录。 1 、 电路构成及原理图 触摸键简单的了解就是一次电容的充放电过程。从原理图可以看出&#xff0c;触摸键 …...

python中字典(dict)原理及其操作

原理 Python中的字典&#xff08;Dictionary&#xff09;是一种基于哈希表&#xff08;Hash Table&#xff09;的实现&#xff0c;提供了高效的键值对&#xff08;Key-Value Pair&#xff09;存储和访问机制。了解字典的工作原理有助于更好地理解其性能特性以及为什么在某些情…...

​​​​​​​​​​​​​​.NET Core Web API实现微服务集群部署

​​​​​​​.NET Core Web API实现微服务集群部署 在.NET Core Web API中实现微服务集群部署通常涉及多个步骤&#xff0c;包括服务拆分、容器化、服务注册与发现、负载均衡等。以下是一个简化的步骤指南&#xff0c;用于在.NET Core中构建和部署微服务集群&#xff1a; 服…...

网络安全与信创产业发展:构建数字时代的护城河

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…...

外包干了3个月,技术倒退1年。。。

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…...

Unity发布webgl获取浏览器的URL

Unity发布webgl获取浏览器的URL Unity发布webgl之后获取浏览器的url 在unity中创建文件夹Plugins&#xff0c;然后添加添加文件UnityGetBrowserURL.jslib var GetUrlFunc {//获取地址栏的URLStringReturnValueFunction: function () {var returnStr window.top.location.hre…...

StarRocks实战——多维分析场景与落地实践

目录 一、OLAP 系统历史背景 1.1 历史背景与痛点 1.2 组件诉求 二、StarRocks 的特点和优势 2.1 极致的查询性能 2.2 丰富的导入方式 2.3 StarRocks 的优势特点 三、多维分析的运用场景 3.1 实时计算场景 / 家长监控中心 3.2 实时更新模型选择 3.2.1 更新模型UNIQU…...

golang 函数式编程库samber/mo使用: Result

golang 函数式编程库samber/mo使用&#xff1a; Result 如果您不了解samber/mo库&#xff0c; 请先阅读上一篇 Option &#xff0c; 这篇讲述结构体Result的使用 Result和Option区别 samber/mo有了Option&#xff0c; 为什么还有Result呢? 我们先看看定义&#xff1a; Opt…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...