一、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/浏览器的事件循环机制相关推荐

  1. 浏览器的事件循环机制

    每个渲染进程都有一个主线程,并且主线程非常繁忙,既要处理 DOM,又要计算样式,还要处理布局,同时还需要处理 JavaScript 任务以及各种输入事件.要让这么多不同类型的任务在主线程中有条不紊地执 ...

  2. 详解浏览器和Node的事件循环机制及区别

    关于事件循环机制(详解) 前言 一.浏览器的事件循环机制 二.Node的事件循环机制 三.两者的区别 前言 JS是单线程的脚本语言,即在同一时间只能做一件事.为了协调时间.用户交互.脚本.UI渲染和网 ...

  3. 事件循环机制 (Event Loop)

    事件循环机制从整体上告诉了我们 JavaScript 代码的执行顺序Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用 ...

  4. 带你了解事件循环机制(Event Loop)

    什么是事件循环机制? 事件循环分为两种,分别是浏览器事件循环和node.js事件循环,本文主要对浏览器事件循环进行描述. 我们都知道JavaScript是一门单线程语言,指主线程只有一个.Event ...

  5. 浏览器中的事件循环机制

    浏览器中的事件循环机制 网上一搜事件循环, 很多文章标题的前面会加上 JavaScript, 但是我觉得事件循环机制跟 JavaScript 没什么关系, JavaScript 只是一门解释型语言, ...

  6. 浏览器事件循环机制与Vue nextTick的实现

    浏览器事件循环机制 先上一段简单的代码 console.log('aa'); setTimeout(() => { console.log('bb')}, 0); Promise.resolve ...

  7. Even Loop(事件循环机制)

    1.什么是事件循环机制 Event Loop即事件循环,是解决javaScript单线程运行阻塞的一种机制. 2.为什么使用Even Loop 原因:JavaScript 是单线程的.单线程就意味着, ...

  8. boost log 能不能循环覆盖_前端基础进阶(十四):深入核心,详解事件循环机制...

    Event Loop JavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了.为了解决自己的这个困扰,在学习的过程中,我一直在试图 ...

  9. js中如何得到循环中的点击的这个id_Js篇面试题9请说一下Js中的事件循环机制

    虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 如果不知道如 ...

最新文章

  1. nginx 网站目录重写
  2. C++ 类型转换(强制类型转换)
  3. boost::promise相关的测试程序
  4. create tablespace 与 heap_insert 函数
  5. 线条边框简笔画图片大全_儿童简笔画画大全人物
  6. mysql客户端报错1366_mysql一些异常
  7. 宣布正式发布 Azure 媒体服务内容保护服务
  8. C#不同操作系统下,界面大小不一的原因
  9. oppo r17进入9008模式
  10. 9 9简单的数独游戏python_python实现数独游戏 java简单实现数独游戏
  11. Qt - 抽签小工具源码
  12. Python 获取微信公众号的图片内容
  13. C++ 逻辑与或非 逻辑与逻辑或 逻辑非
  14. Python几种开发工具介绍
  15. Hive——hive安装
  16. 云计算是继互联网计算机后在信息时代,你知道啥是“云计算”吗?
  17. Android自定义键盘(KeyboardView)
  18. 《TridentNet:Scale-Aware Trident Networks for Object Detection》论文笔记
  19. 如何从0开始在鸿蒙OS中制作一个APP!
  20. 链游开发,链游源码出售,基于Dapp合约的链上游戏

热门文章

  1. 融资租赁系统-覆盖业务全场景数据服务
  2. oracle 权限问题9017,泛微OA 曝出WorkflowCenterTreeData接口注入漏洞(限oracle数据库)
  3. 泰兰德的记忆·悲情伊利丹
  4. 小破练习-嵌套循环及列表
  5. 优达棒球赛数据分析项目
  6. hana经常使用函数
  7. 倍控3865U软路由安装网络行为管控插件Fros
  8. Element-UI 组件MessageBox 弹框 关闭遮罩层
  9. 乐视TV呼叫中心总监李霜:生态时代的服务运营之道
  10. 【Monica的android学习之路】四大组件的生命周期