浏览器中 JS 的事件循环机制
目录
- 事件循环机制
- 宏任务与微任务
- 实例分析
- 参考
1.事件循环机制
浏览器执行JS代码大致可以分为三个步骤,而这三个步骤的往复构成了JS的事件循环机制(如图)。
第一步:主线程(JS引擎线程)中执行JS整体代码或回调函数(也就是宏任务),执行过程中会将对象存储到堆(heap)中,将函数的参数和局部变量加入到栈(stack)中,执行完毕后会释放堆或退出栈。执行完这个宏任务后,会判断微任务队列(microtask queue)是否为空,如果不为空,则会将所有的微任务依次取出并执行。如果在这个过程中触发了任何 Web APIs 将进行第二步操作。
第二步:调用 Web API,并在合适的时候将回调函数加入到事件回调队列(event queue)中。比如执行了setTimeout(callback1, 1000)
,会创建一个计时器,并且在另一个线程(浏览器定时触发线程)里面监听计时器是否过期,等到计时器过期后,会将对应回调 callback1
加入事件回调队列中。
第三步:等到第一步中的微任务执行完毕之后,会判断事件回调队列(event queue)是否为空。如果不为空,则会取出并执行最先进入队列的回调函数,执行过程如同第一步。如果为空,则会视情况进行等待或挂起主线程。
补充说明:浏览器的内核是多线程的,常驻线程有浏览器 GUI 渲染线程、JavaScript 引擎线程、浏览器定时触发器线程、浏览器事件触发线程、浏览器 http 异步请求线程。
2.宏任务与微任务
宏任务(macrotask):script(整体代码)、setTimeout/setInterval、I/O、UI rendering等
微任务(microtask):Promise、MutationObserver等
JS代码执行过程——宏任务与微任务的执行示意图:
如图,可以看出JS执行过程中,是先执行一个宏任务,再执行这个宏任务产生的对应微任务,执行完毕后,再执行后面的宏任务,以此往复。
3.实例分析
使用浏览器:Chrome Version 80.0.3987.163
第一组:
比较 setTimeout 与 Promise
console.log('start')
setTimeout(() => {
console.log('setTimeout')
}, 0);
Promise.resolve().then(() => {
console.log('microtask: promise')
})
console.log('end')
结果:
分析:
以JS的事件循环机制来分析。首先,script(整体代码)算是一个宏任务,执行完毕,会先后输出"start"和"end",然后执行这个过程中产生的微任务,即promis.then中的回调,输出"microtask: promise";这个过程中也调用了 Web API 中的 setTimeout,会创建一个计时器,过期后将回调添加到事件回调队列中;然后再执行回调(第二个宏任务),输出"setTimeout"。与浏览器运行输出一致,符合预期。
第二组:
宏任务与微任务的执行顺序对比
function func1() {
console.log('func1')
Promise.resolve().then(() => {
console.log('microtask.promise1')
})
}
function func2() {
console.log('func2')
Promise.resolve().then(() => {
console.log('microtask.promise2')
})
}
function main() {
func1()
func2()
setTimeout(func1, 0);
setTimeout(func2, 0);
}
main()
结果:
分析:
从输出结果可以看出,当一个宏任务执行完毕后,会接着执行相应的所有微任务,执行完毕后,再执行后续的宏任务,并以往复,与预期相符。
4.参考
JavaScript Event Loop Explained
浏览器中 JS 的事件循环机制的更多相关文章
- 浏览器中的JavaScript事件循环机制
浏览器的事件循环机制是HTML中定义的规范. JavaScript有一个主线程和调用栈,所有的任务都会被放到调用栈等待主线程执行. JS调用栈 是一种先进后出的数据结构.当函数被调用时,会被添加到栈中 ...
- JS JavaScript事件循环机制
区分进程和线程 进程是cpu资源分配的最小单位(系统会给它分配内存) 不同的进程之间是可以同学的,如管道.FIFO(命名管道).消息队列 一个进程里有单个或多个线程 浏览器是多进程的,因为系统给它的进 ...
- Node.js 的事件循环机制
目录 微任务 事件循环机制 setImmediate.setTimeout/setInterval 和 process.nextTick 执行时机对比 实例分析 参考 1.微任务 在谈论Node的事件 ...
- js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)
javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...
- JS:事件循环机制、调用栈以及任务队列
点击查看原文 写在前面 js里的事件循环机制十分有趣.从很多面试题也可以看出来,考察简单的setTimeout也就是考察这个机制的. 在之前,我只是简单地认为由于函数执行很快,setTimeout执行 ...
- js的事件循环机制和任务队列
上篇讲异步的时候,提到了同步队列和异步队列的说法,其实只是一种形象的称呼,分别代表主线程中的任务和任务队列中的任务,那么此篇我们就来详细探讨这两者. 一.来张图感受一下 如果看完觉得一脸懵逼,请继续往 ...
- JS基础-事件循环机制
从一道题浅说 JavaScript 的事件循环 原文链接: https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/7 ...
- js事件循环机制辨析
对于新接触js语言的人来说,最令人困惑的大概就是事件循环机制了.最开始这也困惑了我好久,花了我几个月时间通过书本,打代码,查阅资料不停地渐进地理解他.接下来我想要和大家分享一下,虽然可能有些许错误的 ...
- JS 事件循环机制 - 任务队列、web API、JS主线程的相互协同
一.JS单线程.异步.同步概念 从上一篇说明vue nextTick的文章中,多次出现“事件循环”这个名词,简单说明了事件循环的步骤,以便理解nextTick的运行时机,这篇文章将更为详细的分析下事件 ...
随机推荐
- Redis缓存设计与性能优化
Redis我们一般是用作缓存,扛并发:或者用于某些特定的业务场景,比如前面说到redis各种数据类型的使用场景以及redis的哨兵和集群模式. 这里主要整理了下redis用作缓存,存在的一些问题,以及 ...
- 升级 nop 4.1 Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.
Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement. nop.web 项目 ...
- sql-lib闯关31-40
第三十一关 此关用WAF防护 和第三十关基本一样,在双引号后面添加括号进行闭合 语句可以有两种,?id=-1")union select 1,2,database() --+ 或者 ...
- 搭建SQL server AwaysOn集群
1.环境 系统:windows server 2012 R2 数据库版本:SQL server 2012 三台服务器,IP分别是:10.10.10.111,10.10.10.112,10.10.10. ...
- effective-java学习笔记---使用标记接口定义类型40
标记接口(marker interface),不包含方法声明,只是指定(或“标记”)一个类实现了具有某些属性的接口. 例如,考虑 Serializable 接口.通过实现这个接口,一个类表明它的实例可 ...
- OpenCV-Python 直方图-2:直方图均衡 | 二十七
目标 在本节中, 我们将学习直方图均衡化的概念,并利用它来提高图像的对比度. 理论 考虑这样一个图像,它的像素值仅局限于某个特定的值范围.例如,较亮的图像将把所有像素限制在高值上.但是一幅好的图像会有 ...
- 粒子群优化算法(PSO)之基于离散化的特征选择(FS)(三)
作者:Geppetto 前面我们介绍了特征选择(Feature Selection,FS)与离散化数据的重要性,总览的介绍了PSO在FS中的重要性和一些常用的方法,介绍了FS与离散化的背景,介绍本文所 ...
- 终极指南:构建用于检测汽车损坏的Mask R-CNN模型(附Python演练)
介绍 计算机视觉领域的应用继续令人惊叹着.从检测视频中的目标到计算人群中的人数,计算机视觉似乎没有无法克服的挑战. 这篇文章的目的是建立一个自定义Mask R-CNN模型,可以检测汽车上的损坏区域(参 ...
- CSS基础总结 1
一.什么是 CSS? CSS 指层叠样式表 (Cascading Style Sheets),是一种用来表现 HTML 文档样式的语言,样式定义如何显示 HTML 元素,是能够真正做到网页表现与结构分 ...
- 从上帝视角看Java如何运行
JVM内存结构 可以看出JVM从宏观上可以分为 ‘内部’ 及 ‘外部’ 两个部分(便于记忆理解): ‘内部’包含:线程共享(公有)数据区 和 线程隔离(私有)数据区 ‘外部’包含:类加载子系统.垃 ...