一、概念:事件循环

JavaScript是单线程的

1、整片 script 整体代码(第一个宏任务)放到执行栈中,执行之后,会触发很多方法

这些方法只能一个个的顺序执行,不能并发

2、这些要执行的方法会放到一个称之为事件队列的地方

3、事件队列又分为宏任务队列和微任务队列,所以要执行的方法会被分类到各自类型的队列列表

4、微任务队列的任务是最优先的,只有微任务队列的任务执行完成后,才会去宏任务队列取队头的第一个任务放到执行栈执行

5、之后可能又产生宏任务和微任务,继续步骤4,微任务优先完成,不断循环下去直到所有任务队列的任务清空

这是整体的一个流程

二、分类

下面分类介绍下:

术语:

1)、执行栈:用来执行当前代码

例子:

各个同步代码

a()

b()

c()

2)、宏任务队列:存储宏任务任务

例子:

script 整体代码

setInterval

setTimeout

I/O

UI 交互

setImmediate

3)、微任务队列:存储微任务任务

例子:

Promise.then

process.nextTick

4)、异步请求未完成挂起队列:存储异步耗时任务

例如:未完成的 ajax 请求被挂起

三、流程:

浏览器解析脚本---

解析到的同步代码按照顺序推入执行栈中---

1、顺序执行执行栈中的所有同步代码---

2、执行完执行栈中的所有同步代码,产生 宏任务队列 微任务队列 异步请求未完成挂起队列---

3、此时执行栈为空

4、查看微任务队列是否有任务?

5、有微任务则执行!当次微任务队列全部执行完,微任务队列为空,才去查看宏任务队列

6、没有微任务则直接查看宏任务队列是否有任务,有,取出宏任务队列最前面的任务推入执行栈---

注:在执行微任务宏任务的过程中,异步请求未完成挂起队列中的任务可能已经完成,完成后会推入宏任务队列

7、顺序执行执行栈中的所有同步代码---如此循环

四、练习例子

例子一

// 请写出输出内容 --- 网上搜出来的一个例子
async function async1() {
console.log('async1 start') // 2
await async2()
console.log('async1 end') // 6
}
async function async2() {
console.log('async2') // 3
} console.log('script start') // 1 setTimeout(function() {
console.log('setTimeout') // 8
}, 0) async1() new Promise(function(resolve) {
console.log('promise1') // 4
resolve()
}).then(function() {
console.log('promise2') // 7
})
console.log('script end') // 5 // 输出结果:
// script start
// async1 start
// async2
// promise1
// script end
// async1 end
// promise2
// setTimeout 解析:
第一轮:解析整个代码片段,相当于第一个宏任务在执行栈中执行
此时状态:
执行栈:整片代码段
宏任务队列:null
微任务队列:null 执行过程:
1、遇到 console.log('script start') 直接执行
2、遇到 setTimeout(function() {
console.log('setTimeout')
}, 0)
获得一个宏任务
`function() {
console.log('setTimeout')
}`
3、遇到 async1(),执行后
解析到 console.log('async1 start') 直接执行
然后解析到 await async2()
执行 async2() 后,遇到 console.log('async2') 直接执行
上面执行完成后,await 之后的动作作为一个微任务 `console.log('async1 end')` 被收集
4、遇到 new Promise
直接执行 console.log('promise1'),然后获取一个微任务 `console.log('promise2')`
5、最后直接执行 console.log('script end') 执行后状态:
执行栈:null
宏任务队列:
`function() {
console.log('setTimeout')
}`
微任务队列
`console.log('async1 end')`
`console.log('promise2')` 第二轮:查看执行微任务队列,然后是宏任务队列
此时状态(即上一轮执行后的状态):
执行栈:null
宏任务队列:
`function() {
console.log('setTimeout')
}`
微任务队列
`console.log('async1 end')`
`console.log('promise2')` 执行过程:
1、先看微任务队列是否有任务,先清空微任务队列
将 console.log('async1 end') 拿到执行栈执行
执行完成后 将 console.log('promise2') 拿到执行栈执行
执行完成,执行栈此时为空
2、此时微任务队列都执行完成了,执行栈也为空,从宏任务队列队头取第一个任务
将 function() {
console.log('setTimeout')
} 拿到执行栈执行
执行完成,所有任务都清空,程序结束

### 例子二
```javascript
setTimeout(() =>{
console.log(1)
setTimeout(() =>console.log(2))
setTimeout(() =>console.log(3))
Promise.resolve().then(() => console.log('a'))
.then(() => console.log('b'))
.then(() => console.log('c'))
.then(() => console.log('d'))
})
// 输出结果:1 a b c d 2 3

解析:

1、执行整片代码,产生一个宏任务,没有微任务

宏任务:

() =>{ console.log(1) setTimeout(() =>console.log(2)) setTimeout(() =>console.log(3)) Promise.resolve().then(() => console.log('a')) .then(() => console.log('b')) .then(() => console.log('c')) .then(() => console.log('d')) .then(() => console.log('e')) }

2、将宏任务拿到执行栈执行,陆续执行里面的代码

产生两个宏任务和一个微任务

宏任务:

() =>console.log(2)

() =>console.log(3)

微任务:

() => console.log('a')

3、将一个微任务拿到执行栈执行

此时又产生一个微任务

宏任务:

() =>console.log(2)

() =>console.log(3)

微任务:

() => console.log('b')

4、将一个微任务拿到执行栈执行

此时又产生一个微任务

宏任务:

() =>console.log(2)

() =>console.log(3)

微任务:

() => console.log('c')

5、将一个微任务拿到执行栈执行

此时又产生一个微任务

宏任务:

() =>console.log(2)

() =>console.log(3)

微任务:

() => console.log('d')

6、将一个微任务拿到执行栈执行

微任务执行完成,取宏任务队列队头第一个任务

7、执行 () =>console.log(2) 完后,没有产生微任务,取第二个任务

8、执行 () =>console.log(3) 完后,没有任务,程序结束

聊一聊JavaScript中的事件循环的更多相关文章

  1. 深入理解javascript中的事件循环event-loop

    前面的话 本文将详细介绍javascript中的事件循环event-loop 线程 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与它的用途有关,作为浏览器 ...

  2. JavaScript中的事件循环机制跟函数柯里化

    一.事件循环机制的理解 test();//按秒输出5个5 function test() { for (var i = 0; i < 5; i++) { setTimeout(() => ...

  3. JavaScript中的事件循环

    JavaScript是单线程单并发语言 单线程:主程序只有一个线程,即同一时间片段内其只能执行单个任务. 引发的问题: 单线程,意味着任务都需要排队,前一个任务结束,才会执行后一个任务.若前一个任务耗 ...

  4. javascript 中的事件机制

    1.javascript中的事件. 事件流 javascript中的事件是以一种流的形式存在的. 一个事件会也有多个元素同时响应. 有时候这不是我们想要的效果, 我们只是需要某个特定的元素相应我们的绑 ...

  5. JavaScript中的事件对象

    JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有 ...

  6. JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获

    先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jav ...

  7. 了解javascript中的事件(二)

    本文目录如下: 零.寒暄 一.事件的分类 二.事件代理 2.1 问题引出 2.2 什么是事件代理 2.3 完整示例 二.事件代理 三.事件代理思想的用处 四.总结 零.寒暄 这篇博客本该出现在两个月以 ...

  8. javascript中onclick事件能调用多个方法吗

    Q: javascript中onclick事件能调用多个方法吗? A: 可以的,方法如下onclick="aa();bb();cc();"每个方法用“;”分号隔开就行了

  9. js实例分析JavaScript中的事件委托和事件绑定

    我们在学习JavaScript中,难免都会去网上查一些资料.也许偶尔就会遇到“事件委托”(也有的称我“事件代理”,这里不评论谁是谁非.以下全部称为“事件委托”),尤其是在查JavaScript的事件处 ...

随机推荐

  1. hdu 3060 Area2 (计算几何模板)

    Problem Description 小白最近又被空军特招为飞行员,参与一项实战演习.演习的内容还是轰炸某个岛屿(这次的岛屿很大,很大很大很大,大到炸弹怎么扔都能完全在岛屿上引爆),看来小白确实是飞 ...

  2. C# 语法特性

    C# 2.0 1.泛型(Generics). 2.泛型方法.泛型委托.泛型接口. 3.泛型约束(constraints). 4.部分类(partial). 5.匿名方法. C#3.0/C#3.5 1. ...

  3. (转)将SVN从一台服务器迁移到另一台服务器(Windows Server VisualSVN Server)

    转:http://blog.sina.com.cn/s/blog_855a24030102xp9q.html 服务器环境: Windows Server 2012  软件版本: VisualSVN-S ...

  4. USB仪器控制教程

    概观 本教程是为出发点使用NI-VISA与USB设备进行通信.它不打算作为一个起点,学习USB构架或USB通讯中使用的各种协议.阅读本教程后,您应该能够安装一个USB设备,并使用NI-VISA与该设备 ...

  5. 监控软件munin安装设置

    准备工作需要web环境需要设置epel源 wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-6.repo 服务器端安装设置 y ...

  6. Stimulsoft_Report纯代码实现数据绑定

    Stimulsoft_Report纯代码实现数据绑定 根据穿的参数动态绑定显示报表,涉及多表查询. 一.前台代码: [code]  <%@ Page Title="" Lan ...

  7. 04、python的基础-->列表跟元组

    一.列表list 1.列表的新增元素(三种方法) >>>第1种方法(append 增加到最后): li = ['Peter','Henrry','Wode','鸭子','xiaoxi ...

  8. Eureka 系列(02)Eureka 一致性协议

    目录 Eureka 系列(02)Eureka 一致性协议 0. Spring Cloud 系列目录 - Eureka 篇 1. 服务发现方案对比 1.1 技术选型 1.2 数据模型 2. Eureka ...

  9. 数据转化之JSON

    1.定义:Json(JavaScript Object Notation)是一种轻量级的数据教换模式,简单来说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结 ...

  10. 【题解】sweet

    题目描述 为了防止糖果被小猫偷吃,John把他的糖果放在了很多的高台上,一个高台可以认为是一段平行于X轴的线段,并且高台的y坐标都是大于0的,每个高台都有左端点和高台的长度,每个高台都有糖果.所有的高 ...