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微任务 ), 这图还是很清晰嘛,再来一张 总结一下,就是遇到同步先执行同步,异步的丢到一边依次排队,先排 ...
随机推荐
- select监听服务端
# can_read, can_write, _ = select.select(inputs, outputs, None, None)## 第一个参数是我们需要监听可读的套接字, 第二个参数是我们 ...
- Python学习随笔:使用xlwings设置和操作excel多行多列数据以及设置数据字体颜色填充色对齐方式的方法
☞ ░ 前往老猿Python博文目录 ░ 在前面老猿的文章中,<Python学习随笔:使用xlwings读取和操作Excel文件>.<Python学习随笔:使用xlwings读取和操 ...
- 第8.30节 重写Python __setattr__方法实现属性修改捕获
一. 引言 在<第8.26节 重写Python类中的__getattribute__方法实现实例属性访问捕获>章节介绍了__getattribute__方法,可以通过重写该方法,截获所有通 ...
- 大白话详解大数据hive知识点,老刘真的很用心(1)
前言:老刘不敢说写的有多好,但敢保证尽量用大白话把自己复习的知识点详细解释出来,拒绝资料上的生搬硬套,做到有自己的了解! 01 hive知识点(1) 第1点:数据仓库的概念 由于hive它是基于had ...
- WPF中Logical Tree和Visual Tree的区别
The Logical TreeThe logical tree describes the relations between elements of the user interface. The ...
- Codeforces Edu Round 63 A-E
A. Reverse a Substring 容易看出,只要符合递增顺序就符合\(NO\),否则则可以找到一组,每次记录最大值比较即可. #include <cstdio> #includ ...
- 2020/12月最新WinSpy/WinSpy++下载exe
>>>下载地址 https://wws.lanzous.com/iFUsVj931xa 密码:5hp7 解压密码:yunmuq 夹带私货:在这里希望大家分享文件别再用百度云了,不用百 ...
- centos7 mysql 自动补全
1 yum -y install epel-release #配置erel源 2 yum -y install python-pip 3 pip install mycli #用pip安装 可能会出现 ...
- 利用vs pcl库将多个PCD文件合并成一张PCD地图
主机环境:win10系统,pcl库1.11.1, vs2019 pcl库安装以及环境配置如下连接: https://www.jb51.net/article/190710.htm 代码很简单,主要是做 ...
- sqli-labs 54-65(CHALLANGES)
challenges less-54 less-55 less-56 less-57 less-58 less-59 less-60 less-61 less-62 less-63 less-64 l ...
- setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop