Event loop/浏览器的事件循环机制
一、Event loop引入
1、js为什么是单线程的?
之前我们已经学习了浏览器的关键渲染路径,知道了网页内容交给浏览器后浏览器是如何解析、渲染、绘制的,也提到了浏览器是多线程的,js是单线程的,那么为什么js就是单线程的呢?通过反证法如果js是多线程,多个js任务同时更新同一个dom,一个删除一个修改,这时候浏览器就不知道该如何执行了,故js是单线程的。
2、js为什么需要异步任务?
如果 JavaScript 中不存在异步,只能自上而下执行,如果上一行解析时间很长,那么下面的代码就会被阻塞。对于用户而言,阻塞就意味着"卡死",这样就导致了很差的用户体验,所以 JavaScript 中存在异步执行。
3、什么是Event loop
既然js是单选程的,他要如何执行异步任务呢?因此浏览器通过事件循环机制来解决。那么什么是事件循环机制呢?事件循环的概念非常简单。有一个无休止的循环,JavaScript引擎等待任务,执行任务,然后休眠,等待更多任务。接下来我们以浏览器执行js代码为例,讲解什么是事件循环。
二、Event loop
1、总览
①JS本身是没有办法执行异步任务的,需要环境的支持(如浏览器)
②JS有两个任务队列(宏任务和微任务)和一个任务执行栈,执行栈只能放一个宏任务或者微任务,执行完这个任务后清空执行栈。
③当主线程中js代码全部执行完毕后,这时js解析器会从任务队列中取异步任务来进行执行,根据优先级先取出宏任务执行(一次只取一个执行),执行完毕后,去执行所有的微任务,然后再去取下一个宏任务完成后再去取所有微任务,重复执行上述操作,这种机制就是事件循环。
2、常见的微任务和宏任务
- 常见的微任务包括: promise 的回调、await(本质也是Promise)、node 中的 process.nextTick 、对 Dom 变化监听的 MutationObserver。
- 常见的宏任务包括: script 脚本的执行、setTimeout ,setInterval ,setImmediate 一类的定时事件,还有如 I/O 操作、UI 渲染等。
3、代码演示
<script>function fn(){console.log(1);setTimeout(() => {console.log(2);Promise.resolve().then(() => {console.log(3)});});new Promise((resolve, reject) => {console.log(4)resolve(5)}).then((data) => {console.log(data);Promise.resolve().then(() => {console.log(6)}).then(() => {console.log(7)setTimeout(() => {console.log(8)}, 0);});})setTimeout(() => {console.log(9);})console.log(10);}
fn();
<script>
①第一次事件循环
- script入宏队列
MacroTask Queue(宏任务) |
MicroTask Queue(微任务) |
输出 |
<script>....</script> |
- script入栈
MacroTask Queue(宏任务) |
MicroTask Queue(微任务) |
Call Stack |
<script>....</script> |
- 开始执行同步代码
步骤①: console.log(1);
步骤②: setTimeout入宏队列
步骤③: 执行promise构造函数,promise.then()之后的代码入微任务队列
步骤④: setTimeout入宏队列
步骤⑤:console.log(10);
MacroTask Queue(宏任务) |
MicroTask Queue(微任务) |
输出 |
setTimeout(() => {console.log(2);Promise.resolve().then(() => {console.log(3)}); }); setTimeout(() => {console.log(9); }) |
then((data) => {console.log(data);Promise.resolve().then(() => {console.log(6)}).then(() => {console.log(7)setTimeout(() => {console.log(8)}, 0);}); }) |
1 4 10 |
- 执行微任务1
步骤①:console.log(data);//data为5
步骤②: 执行promise构造函数,promise.then()之后的代码入微任务队列
MacroTask Queue(宏任务) |
MicroTask Queue(微任务) |
输出 |
setTimeout(() => {console.log(2);Promise.resolve().then(() => {console.log(3)}); }); setTimeout(() => {console.log(9); }) |
then(() => {console.log(7)setTimeout(() => {console.log(8)}, 0); }); |
1 4 10 5 6 |
- 继续执行微队列
步骤①:console.log(7)
步骤②:setTimeout入宏队列
MacroTask Queue(宏任务) |
MicroTask Queue(微任务) |
输出 |
setTimeout(() => {console.log(2);Promise.resolve().then(() => {console.log(3)}); }); setTimeout(() => {console.log(9); }) setTimeout(() => {console.log(8) }, 0) |
1 4 10 5 6 7 |
至此第一遍事件循环结束剩下的需要你自己分析喽!
根据分析输出结果为:
输出 |
1 4 10 5 6 7 2 3 9 8 |
完结撒花!
参考文章:
【1】宏任务和微任务_了不起的小瑜儿的博客-CSDN博客基本概念介绍同步异步事件循环机制常见的微任务和宏任务https://blog.csdn.net/qq_43057018/article/details/125128909
【2】浏览器中JS单线程机制与异步的实现_hehaonan~的博客-CSDN博客本文主要讨论浏览器环境上的js单线程机制和js异步的实现,关于其他环境下,比如node就暂时不讨论现来说结论:JS本身是没有办法真正实现异步的,异步的实现需要环境的支持(比如浏览器,因为浏览器是多线程的)。JS有两个任务队列,分别是宏任务(macrotasks)队列和微任务(microtask)队列,JS也只有一个任务执行栈,执行栈只能放一个宏任务或一个微任务,执行完这个任务后清空执行栈。浏览器有一个event table,用来确定宏任务或者微任务何时被添加到相应队列的队尾(个人觉得这个才是https://blog.csdn.net/m0_51218245/article/details/121053965
Event loop/浏览器的事件循环机制相关推荐
- 浏览器的事件循环机制
每个渲染进程都有一个主线程,并且主线程非常繁忙,既要处理 DOM,又要计算样式,还要处理布局,同时还需要处理 JavaScript 任务以及各种输入事件.要让这么多不同类型的任务在主线程中有条不紊地执 ...
- 详解浏览器和Node的事件循环机制及区别
关于事件循环机制(详解) 前言 一.浏览器的事件循环机制 二.Node的事件循环机制 三.两者的区别 前言 JS是单线程的脚本语言,即在同一时间只能做一件事.为了协调时间.用户交互.脚本.UI渲染和网 ...
- 事件循环机制 (Event Loop)
事件循环机制从整体上告诉了我们 JavaScript 代码的执行顺序Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用 ...
- 带你了解事件循环机制(Event Loop)
什么是事件循环机制? 事件循环分为两种,分别是浏览器事件循环和node.js事件循环,本文主要对浏览器事件循环进行描述. 我们都知道JavaScript是一门单线程语言,指主线程只有一个.Event ...
- 浏览器中的事件循环机制
浏览器中的事件循环机制 网上一搜事件循环, 很多文章标题的前面会加上 JavaScript, 但是我觉得事件循环机制跟 JavaScript 没什么关系, JavaScript 只是一门解释型语言, ...
- 浏览器事件循环机制与Vue nextTick的实现
浏览器事件循环机制 先上一段简单的代码 console.log('aa'); setTimeout(() => { console.log('bb')}, 0); Promise.resolve ...
- Even Loop(事件循环机制)
1.什么是事件循环机制 Event Loop即事件循环,是解决javaScript单线程运行阻塞的一种机制. 2.为什么使用Even Loop 原因:JavaScript 是单线程的.单线程就意味着, ...
- boost log 能不能循环覆盖_前端基础进阶(十四):深入核心,详解事件循环机制...
Event Loop JavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了.为了解决自己的这个困扰,在学习的过程中,我一直在试图 ...
- js中如何得到循环中的点击的这个id_Js篇面试题9请说一下Js中的事件循环机制
虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 如果不知道如 ...
最新文章
- nginx 网站目录重写
- C++ 类型转换(强制类型转换)
- boost::promise相关的测试程序
- create tablespace 与 heap_insert 函数
- 线条边框简笔画图片大全_儿童简笔画画大全人物
- mysql客户端报错1366_mysql一些异常
- 宣布正式发布 Azure 媒体服务内容保护服务
- C#不同操作系统下,界面大小不一的原因
- oppo r17进入9008模式
- 9 9简单的数独游戏python_python实现数独游戏 java简单实现数独游戏
- Qt - 抽签小工具源码
- Python 获取微信公众号的图片内容
- C++ 逻辑与或非 逻辑与逻辑或 逻辑非
- Python几种开发工具介绍
- Hive——hive安装
- 云计算是继互联网计算机后在信息时代,你知道啥是“云计算”吗?
- Android自定义键盘(KeyboardView)
- 《TridentNet:Scale-Aware Trident Networks for Object Detection》论文笔记
- 如何从0开始在鸿蒙OS中制作一个APP!
- 链游开发,链游源码出售,基于Dapp合约的链上游戏