javascript的event loop事件循环
javascript的event loop事件循环
这是今天一个朋友发给我的一个面试题,
感觉还挺有意思的,
写个博客以供分享
先看看这个面试题目:
观察下面的代码,写出输出结果
console.log('0')
setTimeout(function () {
console.log('1');
});
new Promise(function(resolve,reject){
console.log('2')
resolve(3)
}).then(function(val){
console.log(val)
})
console.log(4)
输出结果: “0” “2” 4 3 “1”
今天主要是分析为什么输出结果是这样的?这就和 javascript 的执行机制密切相关了.
Event Queue 和 Event Loop
javascript 是一门单线程的语言, 这就意味着在执行代码的时候, 都只有一个主线程来处理所有的任务.
我们都知道 javascript 包括同步代码和异步代码, 那么 javascript 是怎么处理这两种情况的呢?
- 同步和异步任务分别进入不同的执行
场所, 同步的进入主线程,异步的进入Event Table并注册函数 - 当指定的事情完成时,
Event Table会将这个函数(回调函数)移入Event Queue - 主线程内的任务执行完毕为空, 会去
Event Queue读取对应的函数,进入主线程执行 - 上述过程会不断重复, 也就是常说的
Event Loop(事件循环)
这里我们引进了 Event Queue 事件队列这一概念. 所有异步操作的回调都会进入到这里. 然后等到主线程空闲, 就会从这里调取回调执行.
setTimeout
setTimeout 相信大家都有使用过, 可以延时执行并且是异步执行的.
但是有时候我们得到的结果往往是代码实际执行的时间比我们想要延时执行的时间要久。这又是为什么呢?
这就和我们之前所说的 Event Loop 有关了, 我们可以来具体看下 setTimeout 的执行步骤:
setTimeout(function () {
asyncFn()
}, );
syncFn()
asyncFn将异步执行函数放在Event Table, 并且开始计时- 开始执行
syncFn, 但是syncFn可能需要处理的内容很多, 执行时间超过1秒, 但是计时还在继续 - 计时到达
1秒,setTimeout延时完成,asyncFn进入Event Queue事件队列, 但是主线程还在执行, 所以只能等待 syncFn执行完成, 此时asyncFn从事件队列中进入主线程执行
所以有时候会出现代码实际执行时间比延时时间长的情况。
宏任务和微任务
之前我们说过异步任务会进入到事件队列中, 不同类型的任务会进入到不同的队列中, 比如宏任务会进入到宏任务队列中, 微任务会进入到微任务队列中.
微任务:promise
宏任务:setTimeout、setInterval、setImmediate
我们只要记住 当当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行
这时候我们就可以解释一开始的代码执行结果了:
- 主线程执行按顺序代码
- 遇到
setTimeout, 回调进入到宏任务队列上 - 遇到
Promise, 立即执行,then函数进入到微任务队列 - 同步代码执行结束, 主线程检查是否存在微任务, 发现
then, 执行 - 微任务执行完毕, 再去查找宏任务
setTimeout, 执行 setTimeout执行结束, 检查,不存在其他, 结束.
以上。
javascript的event loop事件循环的更多相关文章
- node.js中对Event Loop事件循环的理解
javascript是单线程的,所以任务的执行都需要排队,任务分为两种,一种是同步任务,一种是异步任务. 同步任务是进入主线程上排队执行的任务,上一个任务执行完了,下一个任务才会执行. 异步任务是不进 ...
- 为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?
https://segmentfault.com/a/1190000012806637 https://www.jianshu.com/p/93d756db8c81 首先,请牢记2点: (1) JS是 ...
- Event Loop事件循环,GET!
JS中比较让人头疼的问题之一要算异步事件了,比如我们经常要等后台返回数据后进行dom操作,又比如我们要设置一个定时器完成特定的要求.在这些同步与异步事件里,异步事件肯定是在同步事件之后的,但是异步事件 ...
- 进程,线程,Event Loop(事件循环),Web Worker
线程,是程序执行流的最小单位.线程可与同属一个进程的其他线程共享所拥有的全部资源,同一进程中的多个线程之间可以并发执行.线程有就绪,阻塞,运行三种基本状态. 阮一峰大神针对进程和线程的类比,很是形象: ...
- 浅谈 Event loop (事件循环)
从Event Loop谈JS的运行机制 先来理解一个概念: JS分为同步任务和异步任务 同步任务都在主线程上执行,形成一个执行栈 Execute Content Stack 主线程之外,事件触发线程管 ...
- js event loop事件循环
浏览器环境 以下两段代码是等价的.req对事件的回调设置,实际上就是当前主线程任务队列的任务. var req = new XMLHttpRequest(); req.open('GET', url) ...
- JavaScript event loop事件循环 macrotask与microtask
macrotask 姑且称为宏任务,在很多上下文也被简称为task.例如: setTimeout, setInterval, setImmediate, I/O, UI rendering. mic ...
- Javascript并发模型和事件循环
Javascript并发模型和事件循环 JavaScript的"并发模型"是基于事件循环的,这个并发模型有别于Java的多线程, javascript的并发是单线程的. Javas ...
- JavaScript 如何工作的: 事件循环和异步编程的崛起 + 5 个关于如何使用 async/await 编写更好的技巧
原文地址:How JavaScript works: Event loop and the rise of Async programming + 5 ways to better coding wi ...
随机推荐
- taro初识一
很早之前就听说京东的凹凸实验室发布的开源的一对多的开源框架---Taro,一对多指的是一套代码编译成多端代码使用,极大的节省了开发的效率和成本 废话不多说 第一步,和vue一样下载相应的是cli脚手架 ...
- xxnet to google部署
1,github上下载xxnet项目 2,启动(点击 start) 3,确定启动好后访问 www.google.com (此时是可以访问的) 4,注册google账号或直接登陆 5,访问 https: ...
- 笔记02 linux的一些命令sed
#!/bin/bash # dataformat=`date +%Y-%m-%d-%H-%M` #进行文件件cp并重命名 nginx_home=/opt/modules/nginx-1.12/ cp ...
- 0.3:Before We Start
文章著作权归作者所有.转载请联系作者,并在文中注明出处,给出原文链接. 本系列原更新于作者的github博客,这里给出链接. 需要做的准备 首先肯定是需要安装Unity,我这里选择的版本是Unity ...
- 什么是DNS攻击?它是如何工作的?
什么是DNS攻击?它是如何工作的? DNS攻击是一种利用域名系统中的弱点或漏洞的网络攻击.今天,互联网已成为我们生活中不可或缺的一部分.从社交到金融.购物再到旅游,我们生活的方方面面都是互联网.由于互 ...
- Docker Overlay 介绍
Overlay Network Overlay Network:属于Docker网络驱动,基于VXLAN封装实现Docker原生Overlay网络. Overlay Network:覆盖网络,在基础网 ...
- Docker Swarm 创建服务
Docker Swarm 创建服务 环境: 系统:Centos 7.4 x64 应用版本:Docker 18.09.0 管理节点:192.168.1.79 工作节点:192.168.1.78 工作节点 ...
- Python if条件判断
if else 判断交流 1.判断用户名密码对不对. import getpass _username = 'devin' _password = 'abc123' username = input( ...
- 关于ashrpt中行源的CPU + Wait for CPU事件深入解读
该等待事件并不包含在等待事件范围,而是出现在ash的具体行源中,如下: 标注语句的每次执行大约1小时,如下awr所示: 该sql语句的最后一层Insert如下: insert into ta_tf l ...
- kindeditor4.1.11的使用方法
在引入某个外部框架/功能件的 时候, 通常是 先引入css, 后引入js. css的必要属性是rel和href, js的必要属性是charset和src. js都是用javascript的,所以 cs ...