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

js为什么是单线程的?10分钟了解js引擎的执行机制

  • 1.JS为什么是单线程的? 为什么需要异步? 单线程又是如何实现异步的呢?
  • 2.JS中的event loop(1)
  • 3.JS中的event loop(2)
  • 4.说说setTimeout

首先,请牢记2点:

(1) JS是单线程语言

(2) JS的Event Loop是JS的执行机制。深入了解JS的执行,就等于深入了解JS里的event loop

1. JS为什么是单线程的? 为什么需要异步? 单线程又是如何实现异步的呢?

技术的出现,都跟现实世界里的应用场景密切相关的。

同样的,我们就结合现实场景,来回答这三个问题

(1) JS为什么是单线程的?

JS最初被设计用在浏览器中,那么想象一下,如果浏览器中的JS是多线程的。

这样想,JS为什么被设计成单线程应该就容易理解了吧。

(2) JS为什么需要异步?

 

所以,JS中存在异步执行。

(3) JS单线程又是如何实现异步的呢?

既然JS是单线程的,只能在一条线程上执行,又是如何实现的异步呢?

是通过的事件循环(event loop),理解了event loop机制,就理解了JS的执行机制

2.JS中的event loop(1)

例1,观察它的执行顺序

运行结果是: 1 3 2

也就是说,setTimeout里的函数并没有立即执行,而是延迟了一段时间,满足一定条件后,才去执行的,这类代码,我们叫异步代码。

所以,这里我们首先知道了JS里的一种分类方式,就是将任务分为: 同步任务和异步任务

图片描述

按照这种分类方式:JS的执行机制是

  • 首先判断JS是同步还是异步,同步就进入主进程,异步就进入event table
  • 异步任务在event table中注册函数,当满足触发条件后,被推入event queue
  • 同步任务进入主线程后一直执行,直到主线程空闲时,才会去event queue中查看是否有可执行的异步任务,如果有就推入主进程中

以上三步循环执行,这就是event loop

所以上面的例子,你是否可以描述它的执行顺序了呢?

 

3.JS中的event loop(2)

所以,上面关于event loop就是我对JS执行机制的理解,直到我遇到了下面这段代码

例2:

尝试按照,上文我们刚学到的JS执行机制去分析

所以,结果是 【马上执行for循环啦 — 代码执行结束 — 定时器开始啦 — 执行then函数啦】吗?

亲自执行后,结果居然不是这样,而是【马上执行for循环啦 — 代码执行结束 — 执行then函数啦 — 定时器开始啦】

那么,难道是异步任务的执行顺序,不是前后顺序,而是另有规定? 事实上,按照异步和同步的划分方式,并不准确。

而准确的划分方式是:

  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
  • micro-task(微任务):Promise,process.nextTick

386112937-5a5763d9ef823_articlex

按照这种分类方式:JS的执行机制是

  • 执行一个宏任务,过程中如果遇到微任务,就将其放到微任务的【事件队列】里
  • 当前宏任务执行完成后,会查看微任务的【事件队列】,并将里面全部的微任务依次执行完

重复以上2步骤,结合event loop(1) event loop(2) ,就是更为准确的JS执行机制了。

尝试按照刚学的执行机制,去分析例2:

所以最后的执行顺序是【马上执行for循环啦 — 代码执行结束 — 执行then函数啦 — 定时器开始啦】

4. 谈谈setTimeout

这段setTimeout代码什么意思? 我们一般说: 3秒后,会执行setTimeout里的那个函数

但是这种说并不严谨,准确的解释是: 3秒后,setTimeout里的函数被会推入event queue,而event queue(事件队列)里的任务,只有在主线程空闲时才会执行。

所以只有满足 (1)3秒后 (2)主线程空闲,同时满足时,才会3秒后执行该函数

如果主线程执行内容很多,执行时间超过3秒,比如执行了10秒,那么这个函数只能10秒后执行了

转载于:https://www.cnblogs.com/langzianan/p/8403330.html

相关文章:

  • 鸟哥的linux私房菜学习-(十)vim程序编辑器
  • Linux上vi编辑文件非正常退出后文件恢复
  • 常用网络技术
  • javascript脚本混淆
  • gf框架之grpool - 高性能的goroutine池
  • 谷歌浏览器如何调试JS
  • CocosCreator引擎修改与定制
  • 新年的展望,2018 hello world~
  • Collection---CopyOnWrite(应用于大量度 而少量写的场景)
  • 模块使用
  • 16、sockect
  • USACO 2006 NOV Corn Fields
  • 存储快照实现原理
  • 软件需求模式阅读笔记1
  • centos6之前版本的启动流程
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【Amaple教程】5. 插件
  • 【翻译】babel对TC39装饰器草案的实现
  • conda常用的命令
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • java8 Stream Pipelines 浅析
  • Logstash 参考指南(目录)
  • PHP变量
  • Python连接Oracle
  • Spring Boot MyBatis配置多种数据库
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • SpringBoot几种定时任务的实现方式
  • Vultr 教程目录
  • webpack4 一点通
  • 初识MongoDB分片
  • 翻译:Hystrix - How To Use
  • 分布式熔断降级平台aegis
  • 诡异!React stopPropagation失灵
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 扑朔迷离的属性和特性【彻底弄清】
  • 全栈开发——Linux
  • 我有几个粽子,和一个故事
  • 线性表及其算法(java实现)
  • 译米田引理
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • ​Spring Boot 分片上传文件
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • # 透过事物看本质的能力怎么培养?
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (算法)Travel Information Center
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .net core开源商城系统源码,支持可视化布局小程序