浏览器中的JavaScript事件循环机制
浏览器的事件循环机制是HTML中定义的规范。
JavaScript有一个主线程和调用栈,所有的任务都会被放到调用栈等待主线程执行。
JS调用栈
是一种先进后出的数据结构。当函数被调用时,会被添加到栈中的顶部,执行完成之后就从栈的顶部移除该函数,直到栈内被清空。
同步任务、异步任务
JS单线程任务分为同步任务和异步任务。同步任务会在调用栈中按照顺序排队等待主线程执行,异步任务则会在异步有了结果之后将注册的回调函数添加到任务队列(消息队列)中等待主线程空闲的时候,也就是栈内被清空的时候,被读取到栈中等待主线程执行。任务队列是先进先出的数据结构。
事件循环机制
调用栈中的同步任务都执行完毕,栈内被清空了,就代表主线程空闲了,这个时候就会去任务队列中按照顺序读取一个任务放入到栈中执行。每次栈内被清空,都会去读取任务队列有没有任务,有就读取执行,一直循环读取-执行的操作,就形成了事件循环。
定时器
定时器会开启一条定时器触发线程来触发计时,定时器会在等待了指定的时间后将事件放到任务队列中等待主线程执行。定时器指定的延时毫秒数其实并不准确,因为定时器只是在到了指定的时间将事件放到任务队列中,必须要等到同步的任务和现有的任务队列中的事件全部执行完成之后,才会去读取定时器的事件到主线程执行,中间可能会存在耗时比较久的任务,那么就不可能保证在指定的时间执行。
宏任务、微任务
除了广义的同步任务和异步任务,JavaScript单线程中的任务可以细分为宏任务和微任务。
宏任务:script(整体代码),setTimeout,setInterval,setImmediate,I/O,UI rendering
微任务:process.nextTick,Promises,Object.observe,MutationObserver
补充:在node环境下,process.nextTick的优先级高于Promise,也就是可以简单理解为:在宏任务结束后会先执行微任务队列中的nextTickQueue部分,然后才会执行微任务中的Promise部分。
第一次事件循环中,JavaScript 引擎会把整个 script 代码当成一个宏任务执行,执行完成之后,再检测本次循环中是否存在微任务,存在的话就依次从微任务的任务队列中读取执行完所有的微任务,再读取宏任务的任务队列中的任务执行,再执行所有的微任务,如此循环。JS 的执行顺序就是每次事件循环中的宏任务-微任务。
console.log(1);
setTimeout(function() {
console.log(2);
})
var promise = new Promise(function(resolve, reject) {
console.log(3);
resolve();
})
promise.then(function() {
console.log(4);
})
console.log(5);上面的示例中,第一次事件循环,整段代码作为宏任务进入主线程执行。
遇到了 setTimeout ,就会等到过了指定的时间后将回调函数放入到宏任务的任务队列中。
遇到 Promise,将 then 函数放入到微任务的任务队列中。
整个事件循环完成之后,会去检测微任务的任务队列中是否存在任务,存在就执行。
第一次的循环结果打印为: 1,3,5,4。 宏任务-微任务
接着再到宏任务的任务队列中按顺序取出一个宏任务到栈中让主线程执行,那么在这次循环中的宏任务就是 setTimeout 注册的回调函数,执行完这个回调函数,发现在这次循环中并不存在微任务,就准备进行下一次事件循环。
检测到宏任务队列中已经没有了要执行的任务,那么就结束事件循环。
最终的结果就是 1,3,5,4,2。
谢谢大佬的总结,本文是截取 街边微凉小悲伤 的文章,原版请参考下方链接
https://www.cnblogs.com/yqx0605xi/p/9267827.html
浏览器中的JavaScript事件循环机制的更多相关文章
- 浏览器中 JS 的事件循环机制
目录 事件循环机制 宏任务与微任务 实例分析 参考 1.事件循环机制 浏览器执行JS代码大致可以分为三个步骤,而这三个步骤的往复构成了JS的事件循环机制(如图). 第一步:主线程(JS引擎线程)中执行 ...
- 一篇文章图文并茂地带你轻松学完 JavaScript 事件循环机制(event loop)
JavaScript 事件循环机制 (event loop) 本篇文章已经默认你有了基础的 ES6 和 javascript语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...
- 深入理解JavaScript事件循环机制
前言 众所周知,JavaScript 是一门单线程语言,虽然在 html5 中提出了 Web-Worker ,但这并未改变 JavaScript 是单线程这一核心.可看HTML规范中的这段话: To ...
- 深入浅出Javascript事件循环机制
一.JS单线程.异步.同步概念 众所周知,JS是单线程(如果一个线程删DOM,一个线程增DOM,浏览器傻逼了-所以只能单着了),虽然有webworker酱紫的多线程出现,但也是在主线程的控制下.web ...
- javaScript 事件循环机制
JavaScript是单线程的编程语言,只能同一时间内做一件事.但是在遇到异步事件的时候,js线程并没有阻塞,还会继续执行,这就是因为JS有事件循环机制. 事件循环流程总结 主线程开始执行一段代码, ...
- javascript事件循环机制 浅尝手记
引入 众所周知Javascript是一个单线程的机制,虽然可以依托多线程的浏览器实现页面如何实现页面复杂的渲染.事件响应,但仍不会改变其单线程的本质:所以对于js的事件循环机制的了解是一个前端人员的必 ...
- JS JavaScript事件循环机制
区分进程和线程 进程是cpu资源分配的最小单位(系统会给它分配内存) 不同的进程之间是可以同学的,如管道.FIFO(命名管道).消息队列 一个进程里有单个或多个线程 浏览器是多进程的,因为系统给它的进 ...
- JavaScript事件循环机制
事件循环 事件循环不仅仅包含事件队列,而是具有至少两个队列,除了事件,还要保持浏览器执行的其他操作.这些操作被称为任务,并且分为两类:宏任务(或通常称为任务)和微任务. 单次循环迭代中,最多处理一个宏 ...
- 一道面试题引发对javascript事件循环机制(Event Loop)的 思考(这里讨论针对浏览器)
随机推荐
- Shell07--正则应用
目录 1. 正则表达式概述 2. 正则表达式规则 3. 正则表达式之GREP文本过滤 4. 正则表达式之SED文本处理 5. 正则表达式之AWK文本处理 1. 正则表达式概述 01. 什么是正则表达式 ...
- 使用eclipse创建Spring Boot项目
环境介绍 1.jdk1.8 2.eclipse 3.maven 3.5.0 创建项目 eclectic 左上角 file -> new -> maven project 出现下图默认就好, ...
- maven 配置自动本地/线上不同配置自动打包
工程结构:在resource下新建开发,线上不同文件夹存放不同配置文件 pom.xml配置文件 <!-- maven配置不同环境打包 --> <build> <plugi ...
- 神经网络学习笔记(二):feedforward和feedback
维基百科解释: Feed-forward, sometimes written feedforward, is a term describing an element or pathway with ...
- Spring Transaction Isolation
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11530702.html Reference http://docs.spring.io/spring/ ...
- Linux系统下安装JDK及环境配置
第一种属于傻瓜式安装,一键安装即可(yum安装): 第二种手动安装,需要自己去Oracle官网下载需要的jdk版本(需官网注册登录才可以下载),然后解压并配置环境. 一.yum一键安装1.首先执行以下 ...
- ubuntu软件源变更阿里源和arm板子变更国内源
使用 lsb_release -c 命令,看看当前版本号,替换一下“bionic”字符 1.更改 /etc/apt/sources.list,更改之前先备份一下 deb http://mirrors. ...
- .NET Core 使用 nlog 进行日志记录
1.运行环境 开发工具:Visual Studio 2017 JDK版本:.NET Core 2.0 项目管理工具:nuget 2.GITHUB地址 https://github.com/nbfujx ...
- Apache搭建http网站服务器入门教程
Apache搭建http网站服务器入门教程 准备工具 一台带有Linux系统的主机,这里使用CentOS 7.1 64位系统 一个备案过的域名,这里使用www.hellopage.cn 一台可以访问网 ...
- Oil Deposits( hdu1241
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82828#problem/L Oil Deposits Time Limit:1000MS ...