js事件循环,根据W3C最新说明

2023-11-17

事件循环&&消息循环

首先我们js是一门单线程的语言,这是因为它运行在浏览器的渲染主线程中,而主线程只有一个。那么渲染主线程是如何工作的?

渲染主线程是浏览器中最繁忙的线程,需要它处理的任务包括但不限于:

  • 解析 HTML
  • 解析 CSS
  • 计算样式
  • 布局
  • 处理图层
  • 执行全局 JS 代码
  • 执行事件处理函数
  • 执行计时器的回调函数

要处理这么多的任务,主线程遇到了⼀个前所未有的难题:如何调度任务?

比如:

  • 我正在执⾏⼀个 JS 函数,执⾏到⼀半的时候⽤户点击了按钮,我该⽴即
    去执⾏点击事件的处理函数吗?
  • 我正在执⾏⼀个 JS 函数,执⾏到⼀半的时候某个计时器到达了时间,我
    该⽴即去执⾏它的回调吗?
  • 浏览器进程通知我“⽤户点击了按钮”,与此同时,某个计时器也到达了时
    间,我应该处理哪⼀个呢?

渲染主线程想出了⼀个绝妙的主意来处理这个问题:排队

在这里插入图片描述

  • 在最开始的时候,渲染主线程会进⼊⼀个⽆限循环
  • 每⼀次循环会检查消息队列中是否有任务存在。如果有,就取出第⼀个任务执⾏,执⾏完⼀个后进⼊下⼀次循环;如果没有,则进⼊休眠状态。
  • 其他所有线程(包括其他进程的线程)可以随时向消息队列添加任务。新任会加到消息队列的末尾。在添加新任务时,如果主线程是休眠状态,则会将其唤醒以继续循环拿取任务,这样⼀来,就可以让每个任务有条不紊的、持续的进⾏下去了。

整个过程,被称之为事件循环(消息循环)

何为异步?

代码在执⾏过程中,会遇到⼀些⽆法⽴即处理的任务,⽐如:

  • 计时完成后需要执⾏的任务 —— setTimeout、setInterval
  • ⽹络通信完成后需要执⾏的任务 – XHR、Fetch
  • ⽤户操作后需要执⾏的任务 – addEventListener
    如果让渲染主线程等待这些任务的时机达到,就会导致主线程⻓期处于“阻塞”的状态,从而导致浏览器卡死
    在这里插入图片描述
    因此,浏览器选择异步来解决这个问题
    在这里插入图片描述

任务有优先级吗?

任务没有优先级,在消息队列中先进先出

但消息队列是有优先级的

根据 W3C 的最新解释:

  • 每个任务都有⼀个任务类型,同⼀个类型的任务必须在⼀个队列,不同类型的任务可以分属于不同的队列。
    在⼀次事件循环中,浏览器可以根据实际情况从不同的队列中取出任务执
    ⾏。
  • 浏览器必须准备好⼀个微队列,微队列中的任务优先所有其他任务执⾏

随着浏览器的复杂度急剧提升,W3C 不再使用宏队列的说法 在目前 chrome 的实现中,至少包含了下面的队列:

  • 延时队列:⽤于存放计时器到达后的回调任务,优先级「中」
  • 交互队列:⽤于存放⽤户操作后产⽣的事件处理任务,优先级「⾼」
  • 微队列:⽤户存放需要最快执⾏的任务,优先级「最⾼」
    添加任务到微队列的主要方式是使用 Promise 例如:
// 立即把一个函数添加到微队列
Promise.resolve().then(函数)

最后简单阐述JS事件循环

事件循环⼜叫做消息循环,是浏览器渲染主线程的⼯作⽅式。
在 Chrome 的源码中,它开启⼀个不会结束的 for 循环,每次循环从消息队列中取出第⼀个任务执⾏,⽽其他线程只需要在合适的时候将任务加⼊到队列末尾即可。
过去把消息队列简单分为宏队列和微队列,这种说法⽬前已⽆法满⾜复杂的浏览器环境,取⽽代之的是⼀种更加灵活多变的处理⽅式。
根据 W3C 官⽅的解释,每个任务有不同的类型,同类型的任务必须在同⼀个队列,不同的任务可以属于不同的队列。不同任务队列有不同的优先级,在⼀次事件循环中,由浏览器⾃⾏决定取哪⼀个队列的任务。但浏览器必须有⼀个微队列,微队列的任务⼀定具有最⾼的优先级,必须优先调度执⾏。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

js事件循环,根据W3C最新说明 的相关文章

  • 在 Cordova 中合并文件的多个部分

    在我的 Cordova 应用程序中 我正在下载任意文件 例如图像或视频文件 这是通过 Cordova 文件传输插件和 Range 标头完成的 因为我需要分段下载文件 我的问题是 我想将几 个小 字节 文件合并回原来的文件中 他们曾经在其中使
  • 将 SVG 路径转换为绝对命令

    给定一个 SVG Path 元素 如何将所有路径命令转换为绝对坐标 例如 转换此路径
  • html 图像 src 调用 javaScript 变量

    这是我的代码 我想问 我怎样才能做到这一点 img src img apple 我一直在尝试使用 call 函数和 document onload 但它根本不起作用 有人可以救我吗 我假设你只是想用 javascript 更新图像 src
  • 个人 Tumblr 帖子上的 Javascript

    我知道您可以编辑在 tumblr 博客上呈现所有帖子博客主页的 html AngularJS 但是 有什么办法可以添加自定义到各个帖子 我想在逐个帖子的基础上做一些 javascript 的东西 但似乎无法找到可以编辑代码的位置 或者 如果
  • 如果 CSS 是渲染阻塞的,为什么我们会看到 FOUC?

    为了构建渲染树 浏览器需要 DOM 和 CSSOM CSSOM 只有在下载 CSS 后才能构建 本质上 一旦下载了 CSS 页面就应该可以正常渲染了 但是 为什么我们会在页面上看到 Flash Of Unstyled Content FOU
  • 我应该如何实现将状态保存到 localStorage?

    CODE var React require react var Recipe require Recipe jsx var AddRecipe require AddRecipe jsx var EditRecipe require Ed
  • IE localStorage 事件失火

    在 Internet Explorer 9 和 10 中 localStorage 实现意外地触发事件 这里有很棒的线索 Chrome 的 localStorage 实现存在错误 https stackoverflow com questi
  • JQuery $.ajax() 在 java servlet 中发布数据

    我想将数据发送到 java servlet 进行处理 数据将具有可变长度并采用键 值对 A1984 1 A9873 5 A1674 2 A8724 1 A3574 3 A1165 5 数据不需要这样格式化 这就是我现在的方式 var sav
  • 在 Chrome 开发者工具中禁用调试器语句

    我正在尝试对恶意 JavaScript 进行逆向工程 当我最初加载侧面时 会注入 JS 代码 其中包括 debugger 语句并将断点注入我的 chrome 开发人员控制台 通过stackoverflow阅读 禁用所有断点does not帮
  • 悬停 CSS 仅适用于 Chrome

    嘿 我正在尝试使用 CSS 悬停类 它在 Chrome 上运行良好 但在 Firefox 上运行不佳 任何帮助表示赞赏 这是我的 CSS albumbox labeltext visibility hidden albumbox hover
  • Sphinx内联代码高亮

    我使用 Sphinx 制作一个包含代码示例的网站 我成功地使用了 code block获取语 法高亮的指令 但我无法使用此代码获得内联语法突出显示 role bash code language bash Test inline bash
  • 从请求url获取hash参数

    我有这样的网址 http www coolsite com daily plan id 1 http www coolsite com daily plan id 1解析该字符串并读取哈希值 id 之后的值 的最简单方法是什么 谢谢 在客户
  • 删除下拉链接并在导航栏菜单中显示其所有项目

    我正在使用 Twitter Bootstrap 及其响应式设计来实现顶部典型的 Twitter Bootstrap 导航栏菜单 在那里我有一些链接和一个下拉菜单 当我将浏览器大小调整为768px或者更少 它会转变为一种新的导航菜单 这一切开
  • 悬停时的 CSS 过渡

    我有个问题 实际上 当我将鼠标悬停在对象上时 我尝试在 div 上进行转换 所以基本上我有一个div 当我将鼠标悬停在div上时 它应该在其顶部显示另一个div 但是它应该被转换 这样悬停效果会更平滑 如果我有这两个 div 怎么可能 di
  • 根据文本内容从 jquery 对象中过滤元素

    我正在尝试使用contains带有 this 关键字 但它给出了错误 JS function var check ul find li filter function return this contains two css color r
  • 标题的下边框小于宽度

    我需要创建一个下划线效果底部边框小于h2标题的宽度 通常我不上传图片 但我认为这可能有助于进一步解释问题 您可以为此使用伪元素 例子 http jsfiddle net SZ39x pseudo border position relati
  • ‘state’未定义 no-undef

    我使用教程来学习 React 但我很快就陷入困境 在教程中 他们使用以下代码 import React Component from react class Counter extends Component state count 0 r
  • 从后面的代码添加外部 css 文件

    我有一个 CSS 文件 例如 SomeStyle css 我是否可以将此样式表文档从其代码隐藏应用到 aspx 页面 您可以将文字控件添加到标头控件中 Page Header Controls Add new System Web UI L
  • Safari 扩展将消息发送到特定选项卡

    有没有办法从全局页面发送消息到特定选项卡 我目前正在做的是 在创建选项卡时 注入的脚本会创建一个唯一的 ID 并将包含该编号的消息发送到全局页面 并且全局页面会保存该编号 如果全局页面需要发送一些数据到一个tab 即 tab 3 然后全局页
  • 使用
    元素作为 JavaScript 代码的输入。这是最好的方法吗?

    各位 显然 我是编码新手 所以最近完成了一些有关 HTML 和 Javascript 的 Lynda 课程后 我的简单 HTML 页面遇到了困难 基本上 我想要的是使用 JavaScript 进行基本计算 让用户使用 HTML 输入两个数字

随机推荐

  • DeFi终极指南【以太坊去中心化金融】

    DeFi De centralized Fi nance 即去中心化金融 是2019年区块链应用发展最迅猛的一个领域 在以太坊区块链上那些最成功的DApp 例如MakerDAO DAI Compound 0x以及下面我们要介绍的那些 其目标
  • 关于matlab中矩阵取值的方法

    在matlab中 取出矩阵中某一个值的方法如下 1 对于二维数组 a i j 表示取出二维数组a的第 i 行 第 j 列的数据 a j 表示取出二维数组a的第 j 列的所有数据 a i 表示取出二维数组a的第 i 行的所有数据 2 多维数组
  • Aviator 表达式的使用

    1 使用Aviator 需要导入包
  • 计算机视觉人体骨骼点动作识别-1.训练自己的关键点检测模型

    人体关键点检测算法 关键点并不特指人体骨骼关键点 还有人脸关键点 物体的关键点 其中人体的关键点 也叫作pose Estimation 是最热门 也是最有难度 应用最广的 应用可以包括 行为识别 人机交互 智能家居 虚拟现实 具体细分下来可
  • USB之基础知识

    1 USB概述 USB Universal Serial Bus 通用串行总线 是一个外部总线标准 用于规范电脑与外部设备的连接和通讯 USB接口支持设备的即插即用和热插拔功能 USB接口有4个pin脚 分别为VCC GND Data Da
  • 通过tomcat.mamager页面远程管理tomcat

    通过java访问tomcat的manager来管理 此方法无法达到重启tomcat的目的 只能重启应用 先在tomcat中修改tomcat users xml
  • 嵌入式Linux编译系统的设计——Bootloader, 内核,驱动,文件系统,升级镜像等自动化编译打包

    项目简介 嵌入式系统的开发过程较为复杂 编译 裁剪 定制等如果没有一套规范的流程将会难于管理和控制 本项目的目的是设计一个嵌入式Linux编译系统 实现代码的编译 定制和裁剪 Bootloader 内核 驱动 文件系统 升级镜像等都可以自动
  • 前端将静态页面放在移动端上,查看效果

    想要将本地刚写完的静态HTML文件 放在移动端上查看 不是放在浏览器中 打开移动端模式 需要进行一下步骤 1 全局安装 node 具体步骤看官网 2 在全局运行 cmd 输入 npm install anywhere g 3 打开静态资源
  • 前端例程20220920:纯CSS图片自动轮播效果

    演示 原理 代码
  • tp5实现短信注册,调用第三方接口,电话通知,和短信通知都可以。

    thinkphp5实现短线验证注册 思路 1 一个表单 表单中要有一个手机字段 和密码 2 在提交验证码添加点击事件 触发ajax 请求后台 发送短信 3 后台中编写控制器方法 一个ajax请求发送短信 一个表单验证成功条页面 4 在con
  • OpenCV copyTo操作会覆盖原数据

    前言 有一些指导说copyTo只会覆盖对应区域 这边做了一个测试 测试 测试代码 int main Mat photo1 imread home evening 桌面 5 png if photo1 data cout lt lt erro
  • Your account has been blocked. git更新代码时报错

    记录一下问题 原因解释 当前用户登录信息过期 在浏览器里登录gitlab后台 长时间没有重新登录 导致后端登录session失效 自动锁住用户账号 此时通过ssh下载也就无法更新代码 解决办法 在浏览器重新登录gitlab网站 然后重新更新
  • 【tomcat】应用服务

    准备环境 三台虚拟机 192 168 1 120 192 168 1 122 192 168 1 131 三台虚拟机关闭防火墙 查看光盘 检测yun创库 查看JDK是否安装 root localhost java version openj
  • 蓝桥杯 - 负载均衡

    输入样例 2 6 5 5 1 1 5 3 2 2 2 6 3 1 2 3 4 1 6 1 5 1 3 3 6 1 3 4 输出样例 2 1 1 1 1 0 解析 优先队列 排序规则为任务结束的时间 在新任务的时候 弹出已经结束的任务 并且恢
  • 什么是自动与自主?

    自动与自主的区别很有意思 平时大家都不爱斟酌 一般都是拿过来就用 岂不知 西方人常常不是这样子的 他们一般先从基本概念上进行咬文嚼字般的抠 然后在此基础上进行理论过程的推导演算或实验实践的验证分析 于是差距往往就此拉开 自主 自建构 系统中
  • virtio-netdev 发送数据包

    在前面几文中已经大体介绍了virtio的重要组成 包含virtio net设备的创建 vring的创建 与virtio设备的交互方式 我们就从网络数据包的发送角度来看下virtio的详细使用流程 点击查看全文 http luoye me 2
  • 网络编程1

    网络编程 网络编程是Java最擅长的方向之一 使用Java进行网络编程时 由虚拟机实现了底层复杂的网络协议 Java程序只需要调用Java标准库提供的接口 就可以简单高效地编写网络程序 1 前置知识点 学习网络编程之前 我们需要先了解什么是
  • HttpRunner 3.x接口自动化: 全面讲解如何落地实战

    今天 我们来一起学习下HttpRunner3 主要讲解如何使用 应用技巧 基本知识点总结和需要注意事项 一篇文章没法面面俱到 如果有重要的地方没写到 可以给我留言 咱们接着补充 整体概览 概述介绍 HttpRunner 是一款面向 HTTP
  • VSCODE远程ssh调试linux+cpolar内网穿透

    VSCODE远程ssh调试linux cpolar内网穿透 一 cpolar配置与使用 1 进入cpolar官网https i cpolar com m 4kqU 2 点击免费使用 进行账号注册 3 linux安装cpolar 国内安装 c
  • js事件循环,根据W3C最新说明

    事件循环 消息循环 首先我们js是一门单线程的语言 这是因为它运行在浏览器的渲染主线程中 而主线程只有一个 那么渲染主线程是如何工作的 渲染主线程是浏览器中最繁忙的线程 需要它处理的任务包括但不限于 解析 HTML 解析 CSS 计算样式