JS 执行机制 详解(附图)

news2024/12/21 19:13:19

一、JS是单线程

JS语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是JS这门脚本语言诞生的使命所致——用来处理页面中用户的交互,以及操作DOM而诞生的。

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果JS执行的时间过长,这样会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉

二、同步和异步

为了解决这个问题,利用多核CPU的计算能力,HTML5提出了Web Worker标准,允许JS脚本创建多个线程,于是,jS中出现了同步和异步

同步:前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的,同步的。比如:我们要烧水煮饭,等水开了(10分钟后),再去切菜,炒菜

异步:你在做一件事情时,因为这件事会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如烧水的10分钟内,去切菜,炒菜

同步任务在主线程上排队执行任务,只有前一个任务执行完毕,才能执行后一个任务

异步任务:不进入主线程,而是进入"任务队列"的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

一般而言,异步任务有以下四种类型

  • setTimeout和setlnterval

  • DOM事件 普通事件如:click、resize,资源加载事件:onload等

  • ES6中的Promise

  • Ajax异步请求

异步任务相关回调函数添加到任务队列中(消息队列)

三、JS执行机制

  1. 先执行执行栈中的同步任务

  1. 异步任务(回调函数)放入任务队列中

  1. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行

let setTimeoutCallBack = function() {
  console.log('我是定时器回调');
};
let httpCallback = function() {
  console.log('我是http请求回调');
}

// 同步任务
console.log('我是同步任务1');

// 异步定时任务
setTimeout(setTimeoutCallBack,1000);

// 异步http请求任务
ajax.get('/info',httpCallback);

// 同步任务
console.log('我是同步任务2');

上述代码执行过程:

JS是按照顺序从上往下依次执行的,可以先理解为这段代码时的执行环境就是主线程,也就是当前执行栈

首先,执行console.log(‘我是同步任务1’)

接着,执行到setTimeout时,会移交给定时器线程,通知定时器线程 1s 后将setTimeoutCallBack 这个回调交给事件触发线程处理,在 1s 后事件触发线程会收到 setTimeoutCallBack 这个回调并把它加入到事件触发线程所管理的事件队列中等待执行

接着,执行http请求,会移交给异步http请求线程发送网络请求,请求成功后将 httpCallback 这个回调交由事件触发线程处理,事件触发线程收到 httpCallback 这个回调后把它加入到事件触发线程所管理的事件队列中等待执行

再接着执行console.log(‘我是同步任务2’)

至此主线程执行栈中执行完毕,JS引擎线程已经空闲,开始向事件触发线程发起询问,询问事件触发线程的事件队列中是否有需要执行的回调函数,如果有将事件队列中的回调事件加入执行栈中,开始执行回调,如果事件队列中没有回调,JS引擎线程会一直发起询问,直到有为止

由此可以看出,浏览器上的所有线程的工作都很单一且独立,非常符合单一原则

定时触发线程 只管理定时器且只关注定时不关心结果,定时结束就把回调扔给事件触发线程

异步http请求线程 只管理http请求同样不关心结果,请求结束把回调扔给事件触发线程

事件触发线程 只关心异步回调入事件队列

JS引擎线程 只会执行执行栈中的事件,执行栈中的代码执行完毕,就会读取事件队列中的事件并添加到执行栈中继续执行,这样反反复复就是我们所谓的事件循环(Event Loop)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/371160.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++014-C++字符串

文章目录C014-C字符串字符串目标char[]和stringchar[]char*string字符常量与字符串常量字符串的输入题目描述 字符串输出题目描述在线练习:总结C014-C字符串 在线练习: http://noi.openjudge.cn/ https://www.luogu.com.cn/ 字符串 目标 1、了解字符串…

OAuth2.0从入门到实战(附github地址)

OAuth2.0 文章目录OAuth2.0OAuth2.0的含义与思想[快递员的例子]([OAuth 2.0 的一个简单解释 - 阮一峰的网络日志 (ruanyifeng.com)](https://www.ruanyifeng.com/blog/2019/04/oauth_design.html))互联网的例子令牌与密码OAuth2.0的四种授权方式RFC 6749一、授权码(前后端分离)…

Vue3电商项目实战-商品详情模块6【17-商品详情-标签页组件、18-商品详情-热榜组件、19-商品详情-详情组件、20-商品详情-注意事项组件】

文章目录17-商品详情-标签页组件18-商品详情-热榜组件19-商品详情-详情组件20-商品详情-注意事项组件17-商品详情-标签页组件 目的:实现商品详情组件和商品评价组件的切换 大致步骤: 完成基础的tab的导航布局完成tab标签页的切换样式效果使用动态组件完…

【设计模式】 策略模式介绍及C代码实现

【设计模式】 策略模式介绍及C代码实现 背景 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂,而且有时候支持不使用的算法也是一个性能负担。 如何…

go单元测试

接着上一篇中的go module创建项目calc为例,在simplemath包中,是使用在命令行中使用交互式的方式进行测试,现在可以为这几个函数实现单元测试, go test,这个测试工具来自于 Go 官方的 gc 工具链。 运行 go test 命令将执…

JVM本地方法接口和本地方法栈

1、本地方法概述简单地讲,一个Native Method是一个Java调用非Java代码的接囗。一个Native Method是的实现由非Java语言实现,比如C。这个特征并非Java所特有,很多其它的编程语言都有这一机制,比如在C中,你可以用extern …

openpnp - 零碎记录

文章目录openpnp - 零碎记录概述笔记配置文件保存无效ENDopenpnp - 零碎记录 概述 这段时间, 正在配置校准手头的openpnp设备, 用的官网最新的openpnp2.0. 由于openpnp的bug和自己的不细致, 导致多次校准失败. 现在从头校准时, 每进行一步, 就保存一下配置文件, 如果最终发现…

MySQL_主从复制读写分离

主从复制 概述 主从复制是指将主数据库的DDL和DML操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。 MySQL支持一台主库同时向多台从库进行复制,从…

leetcode 31~40 学习经历

leetcode 31~40 学习经历31. 下一个排列32. 最长有效括号33. 搜索旋转排序数组34. 在排序数组中查找元素的第一个和最后一个位置35. 搜索插入位置36. 有效的数独37. 解数独38. 外观数列39. 组合总和40. 组合总和 II小结31. 下一个排列 整数数组的一个 排列 就是将其所有成员以序…

3.JVM内存分配机制详解【2023】

redis跳表 内容概要 内存分配 1.类加载检查 😊虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个 符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执…

MySQL/Oracle获取当前时间几天/分钟前的时间

获取当前时间 要想获取当前时间几天/分钟前的时间,首先要知道怎么获取当前时间; 对于MySQL和Oracle获取当前时间的方法是不一样的; MySQL: select NOW(); 示例: Oracle: select sysdate from dual; 示…

西北工业大学2020-2021学年大物(I)下期末试题选填解析

2 位移电流。磁效应服从安培环路,热效应不服从焦耳-楞次定律。注意,它是变化的电场而非磁场产生。3 又考恒定磁场中安培环路定理。4感生电场5 麦克斯韦速率分布函数。6 相同的高温热源和低温热源之间的一切可逆热机的工作效率相等,无论工质如…

java 内部类的四种“写法”

基本介绍语法格式分类成员内部类静态内部类局部内部类匿名内部类(🐂🖊)一、基本介绍 : 1.概述当一个类的内部又完整地嵌套了另一个类时,被嵌套于内部的“内核”我们称之为“内部类”(inner class);而包含该…

Airbyte,数据集成的未来

Gartner 曾预计,到 2025 年,80% 寻求扩展数字业务的组织将失败。因为他们没有采用现代方法来进行数据和分析治理。数据生态是基础架构生态的最重要一环,数据的处理分发与计算,从始至终贯穿了整个数据流通生态。自从数据集中在数据…

3. Unity之三维模型

1. 网格 Mesh 三维物体模型在unity中一般称为mesh,即网格数据,模型一般使用专用的建模软件设计,将mesh文件导入到unity中进行使用,一般mesh中保存的是三维模型的面和顶点数据。在unity中通过下图方法进行调整,其中&am…

MakeFile教程

前言 当我们需要编译一个比较大的项目时,编译命令会变得越来越复杂,需要编译的文件越来越多。其 次就是项目中并不是每一次编译都需要把所有文件都重新编译,比如没有被修改过的文件则不需要重 新编译。工程管理器就帮助我们来优化这两个问题…

Elasticsearch7.8.0版本进阶——IK中文分词器

目录一、ES 的默认分词器测试示例二、IK 中文分词器2.1、IK 中文分词器下载地址2.2、ES 引入IK 中文分词器2.3、IK 中文分词器测试示例三、ES 扩展词汇测试示例一、ES 的默认分词器测试示例 通过 Postman 发送 GET 请求查询分词效果,在消息体里,指定要分…

python社团 培训记录(自2023年2月24日始)

在单位开设了Python社团,在此记录上课的有关情况: 课程概述:本社团主要针对五、六年级,初始招生(上课前)28人(五、六年级各14人),后(上课时)人员…

一文让你彻底理解Linux内核调度器进程优先级

一、前言 本文主要描述的是进程优先级这个概念。从用户空间来看,进程优先级就是nice value和scheduling priority,对应到内核,有静态优先级、realtime优先级、归一化优先级和动态优先级等概念。我们希望能在第二章将这些相关的概念描述清楚。…

优秀的网络安全工程师应该有哪些能力?

网络安全工程师是一个各行各业都需要的职业,工作内容属性决定了它不会只在某一方面专精,需要掌握网络维护、设计、部署、运维、网络安全等技能。目前稍有经验的薪资在10K-30K之间,全国的网络安全工程师还处于一个供不应求的状态,因…