setTimeout 是到了xx ms 就执行吗,了解浏览器的 Event-Loop 机制
要想 JavaScript 玩得溜,还得了解波 JavaScript 执行机制/(ㄒoㄒ)/~~。
个人博客:https://shansan.top
前言
最近看了波 JavaScript 相关的文章,不得不说,JavaScript 我还真没玩明白(给我哭~。。。)。也挺久没写文了,实习(“摸”)之余小记一波。
回顾一句话:JavaScript 是一门单线程、非阻塞、异步、解释性脚本语言。
本文的标题是:setTimeout 是到了xx ms 就执行吗,了解 Event-Loop 机制。先回答波:不是。
来看下网上的一段经典 js 代码在浏览器中「Microsoft Edge 84.0.522.63(64位)」的执行结果。
console.log('script start');
setTimeout(() => {
console.log('setTimeout');
},0);
Promise.resolve().then(() => {
console.log('promise1');
}).then(() =>{
console.log("promise2");
});
console.log('script end');
可以明显看到 setTimeout
的 callback 并非在 0 ms 后立即执行。那么,这是问什么?要了解原因,需要了解后续介绍的 Event Loop 机制。
概念一览
- 浏览器的内核-多线程的渲染进程:页面的渲染、js 的执行、事件的循环都在渲染进程中进行。渲染进程主要包含以下几个线程:
{% fancybox %}
{% endfancybox %}
- Task:Task 有 MicroTask 和 MacroTask 之分,MicroTask 在 Promise 出现之后引入。MacroTask 和 MicroTask 分别在以下几种场景形成:
- MacroTask:主代码块、setTimeout、setInterval、IO 事件等。
- MicroTask:Promise、process.nextTick 等。
浏览器中的Event Loop
有了基础概念,让我们来了解一下文章开头给出的代码是怎么执行的,代码如下:
console.log('script start');
setTimeout(() => {
console.log('setTimeout');
},0);
Promise.resolve().then(() => {
console.log('promise1');
}).then(() =>{
console.log("promise2");
});
console.log('script end');
- 1、首先,整个代码块作为第一个 MacroTask 被执行,同步的代码直接被压入执行栈被执行「同步任务在JS引擎线程上执行」,script start 和 script end 被打印;
- 2、setTimeout 被作为 MacroTask 处理,加入宏任务队列中;
- 3、Promise 被作为 MicroTask 处理,加入微任务队列中;
- 4、本次 MacroTask 处理完毕,检查微任务队列,发现 promise then 的 callback,promise1,promise2 先后打印;
- 5、接下来执行下一个 MacroTask,即 setTimeout 推送给任务队列的 callback,打印 setTimeout。
so,代码执行结果如下:
script start
script end
promise1
promise2
setTimeout
由此,可大致了解到浏览器下 Event-Loop 执行机制大致如下:
{% folding open red, Event-Loop 执行机制 %}
- 1、一开始,整段脚本被当作 MacroTask 执行
- 2、执行过程中,同步代码进入可执行栈中直接执行,MacroTask 进入宏任务队列,MicroTask 进入微任务队列
- 3、当前 MacroTask 执行完就出队,检查微任务队列,如果不为空,则依次执行微任务队列中的 MicroTask,直到微任务队列为空
- 4、执行浏览器的 UI 线程的渲染工作「两个 MicroTask 执行空隙,有次 render 工作」
- 6、执行队首的 MacroTask,回到 2,依此循环,直至宏任务队列和微任务队列都为空
可通过下图简单理解一波:
{% endfolding %}
由此可知道,setTimeout 中的 callback 不能按时执行是因为 Event-Loop,导致 JS 引擎线程还有其它的 task (promise MicroTask)要处理,主线程还未空闲下来。
参考
- What the heck is the event loop anyway?「很精彩的演讲
setTimeout 是到了xx ms 就执行吗,了解浏览器的 Event-Loop 机制的更多相关文章
- setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop
笔者以前面试的时候经常遇到写一堆setTimeout,setImmediate来问哪个先执行.本文主要就是来讲这个问题的,但是不是简单的讲讲哪个先,哪个后.笼统的知道setImmediate比setT ...
- 解读setTimeout, promise.then, process.nextTick, setImmediate的执行顺序
最近在看<Node.js调试指南>的时候遇到有意思的几道题,是关于setTimeout, promise.then, process.nextTick, setImmediate的执行顺序 ...
- 【Node.js】Event Loop执行顺序详解
本文基于node 0.10.22版本 关于EventLoop是什么,请看阮老师写的什么是EventLoop 本文讲述的是EventLoop中的执行顺序(着重讲setImmediate, setTime ...
- 以setTimeout来聊聊Event Loop
平时的工作中,也许你会经常用到setTimeout这个方法,可是你真的了解setTimeout吗?本文想通过总结setTimeout的用法,顺便来探索javascript里面的事件执行机制. setT ...
- 定时器setTimeout()和Node.js的Event Loop
一.定时器 setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行.它在"任务队列"的尾部添加一个事件,因此要等到同步任务和 ...
- 【原】以setTimeout来聊聊Event Loop
平时的工作中,也许你会经常用到setTimeout这个方法,可是你真的了解setTimeout吗?本文想通过总结setTimeout的用法,顺便来探索javascript里面的事件执行机制. setT ...
- setTimeout 的黑魔法 【event loop】
setTimeout,前端工程师必定会打交道的一个函数.它看上去非常的简单,朴实.有着一个很不平凡的名字--定时器.让年少的我天真的以为自己可以操纵未来.却不知朴实之中隐含着惊天大密.我还记得我第一次 ...
- javascript的执行机制—Event Loop
既然今天要谈的是javascript的事件循环机制,要理解事件循环,首先要知道事件循环是什么. 我们先从一个例子来看一下javascript的执行顺序. <script> setTimeo ...
- 再次聊一聊promise settimeout asycn awiat执行顺序---js执行机制 EVENT LOOP
首先js是单线程 分为同步和异步,异步又分为(macrotask 宏任务 和 microtask微任务 ), 这图还是很清晰嘛,再来一张 总结一下,就是遇到同步先执行同步,异步的丢到一边依次排队,先排 ...
随机推荐
- 容器中实现拉取其它服务器的jar包程序
缘由:在做接口自动化测试时,若业务场景有一个前置仓库,在该仓库内完成一系列的场景测试,一旦某一场景测试失败,脏数据对环境造成影响则需要清理: 1.我容器的内核系统为Debian GNU/Linux 1 ...
- 【译】理解Rust中的局部移动
原文标题:Understanding Partial Moves in Rust 原文链接:https://whileydave.com/2020/11/30/understanding-partia ...
- LeetCode 042 Trapping Rain Water
题目要求:Trapping Rain Water Given n non-negative integers representing an elevation map where the width ...
- Spring Boot 集成 MQTT
本文代码有些许问题,处理方案见:解决 spring-integration-mqtt 频繁报 Lost connection 错误 一.添加配置 spring: mqtt: client: usern ...
- Spring Cloud 学习 (六) Spring Cloud Config
在实际开发过程中,每个服务都有大量的配置文件,例如数据库的配置.日志输出级别的配置等,而往往这些配置在不同的环境中也是不一样的.随着服务数量的增加,配置文件的管理也是一件非常复杂的事 在微服务架构中, ...
- day1(ModelViewSet序列化限流排序)
1.DRF初始化 1.认证 2.权限 3.限流 4.序列化 5.分页 6.版本 7.过滤 8.排序 1.1安装DjangoRestFramework pip install djangoresfra ...
- ERP费用报销操作与设计--开源软件诞生31
赤龙ERP费用报销讲解--第31篇 用日志记录"开源软件"的诞生 [进入地址 点亮星星]----祈盼着一个鼓励 博主开源地址: 码云:https://gitee.com/redra ...
- Python中序列解包与函数的参数收集之间的关系
在<第4.7节 Python特色的序列解包.链式赋值.链式比较>中老猿介绍了序列解包,<第5.2节 Python中带星号的函数参数实现参数收集>介绍了函数的参数收集,实际上函数 ...
- 第11.9节 Python正则表达式的贪婪模式和非贪婪模式
在使用正则表达式时,匹配算法存在贪婪模式和非贪婪模式两种模式,在<第11.8节 Pytho正则表达式的重复匹配模式及元字符"?". "*". " ...
- PyQt(Python+Qt)学习随笔:Qt Designer中怎么给toolBar添加按钮
在Designer中创建了一个MainWindow窗体,当想在其中的toolBar中添加toolButton时发现怎么也放不上去,最终才发现toolBar中的按钮只能通过直接拖拽Action编辑器中的 ...
- setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop