JavaScript全解析——事件轮询EventLoop
JS 是一门单线程语言 (换句话说: 一个时间内我只能做一件事), 异步操作都是放到事件循环队列中, 等待主执行栈来执行
JS 是如何执行的 (执行顺序)
●从上往下, 一行一行执行
●如果中间的某一行书写有误, 那么程序在运行到这一行会报错并停止向下继续运行
●先把所有的同步代码执行完毕, 然后再开始执行异步代码
EventLoop 是什么
其实就是一种执行方式, 当主线程的任务执行完毕后, 会通过轮询, 轮询事件队列(也有人叫做回调队列)当中的任务的方式去执行任务, 如果事件队列中的任务为空, 会一直轮询, 通过事件轮询推入主线程
EventLoop 的规则是什么
● 从宏任务开始
●每执行完毕一个宏任务, 就会清空一次微任务队列(不管微任务队列有多少任务, 都执行完毕)
●然后再次执行一个宏任务
●循环往复, 直到所有任务队列全都清空
宏任务宇微任务是什么
●在 JS 中, 代码分为了两种, 同步和异步
●异步任务中也分为了两种, 宏任务与微任务
○宏任务: 'script 整体代码, setTimeout, setInterval 等...'
○微任务: 'Promise.then(), process.nextTick(NodeJs), MutationObserver(H5新特性)...'
案例分析
console.log(1)
setTimeout(() => console.log(2), 0)
Promise.resolve().then(() => console.log(3))
console.log(4)
●具体流程
1.根据 EventLoop 的规则, 从宏任务开始, 因为 script 就算一个宏任务, 所以此时会先将它内部的所有 同步代码执行完毕
a. 代码从上往下执行, 在第一行遇到了一个 console.log(1), 属于同步代码, 直接执行 (打印1)
b.向下执行中, 遇到一个 setTimeout 推入到 宏任务队列
c.向下继续执行, 遇到一个 promise.then(), 推入到微任务队列
d.最后遇到了一个 console.log(4), 属于同步代码, 直接打印 (打印4)
2. 根据 EventLoop 的规则, 此时执行完毕一个 宏任务, 那么会清空微任务队列
a.微任务队列中只有一个 promise.then, 内部的代码为 console.log(3)
b.所以清空完毕微任务队列后, 控制台多了一个 打印 3
3. 根据 EventLoop 的规则, 此时会继续执行下一个宏任务
a.目前宏任务队列中的任务为 setTimeout, 内部的代码为 console.log(2)
b.所以执行完 当前宏任务后, 控制台多了一个 打印 2
4. 根据 EventLoop 的规则, 此时会清空微任务队列, 但是此时微任务内没有任何任务
5. 根据 EventLoop 的规则, 此时会查看宏任务队列, 但是此时宏任务内也没有任何任务
6. 程序到此已全都执行完毕
7. 最终的打印结果: '1, 4, 3, 2'
如果在宏任务执行过程中又开启了一个微任务如何执行?
●代码
console.log(1)
setTimeout(() => {
console.log(2)
Promise.resolve().then(() => {
console.log(3)
})
})
new Promise((resolve, reject) => {
console.log(4)
resolve(5)
}).then((data) => {
console.log(data);
return 6;
}).then((data)=>{
console.log(data)
})
setTimeout(() => {
console.log(7);
})
console.log(8);
● 执行流程
一、执行 script 中的所有代码
1、console.log(1); 同步任务 直接打印
2、setTimerout; 异步任务, 推入宏任务队列
3、new Promise 中的代码属于同步任务, 但是 后续的 then 属于异步任务; 所以会执行 console.log(4); 并推入 then 到微任务队列
4、setTimerout; 异步任务, 推入宏任务队列 (在此之前已经有一个了)
5、console.log(8); 同步任务直接打印
6、此时控制台打印: '1, 4, 8'
二、根据规则, 此时执行完毕一个宏任务, 所以会去清空微任务队列中的任务
1、此时微任务队列中的是 之前的 promise 的 then 方法, 因为 promise中 resolve的值为 5, 所以此时打印的值是 5
2、这个 then 方法执行完毕会 return 一个 6, 所以后续的 then 方法会继续执行, 所以打印的是 6
3、此时控制台打印: '5, 6'
三、根据规则, 此时会微任务队列已清空, 所以会执行下一个宏任务
1、此时会执行第一个 setTimetou
2、内部代码第一个为 console.log(2), 所以会直接打印
3、后续的代码为一段 promise, 注意: "此时会将这个promise推入微任务队列中"
4、此时控制台打印: '2'
四、执行完毕一个宏任务后, 再次清空微任务队列
1、此时就只有第三步中的 promise 这一个微任务了
2、这个微任务执行时会打印 3
3、此时控制台打印: '3'
五、微任务队列清空完毕后继续执行宏任务
1、此时就只剩下最后一个 setTimeout 了
2、执行内容为 console.log(7)
3、此时控制台打印: '7'
六、最终的打印结果: '1, 4, 8, 5, 6, 2, 3, 7'
猜你喜欢LIKE
相关推荐HOT
更多>>servlet底层原理是什么?
1、ServletAPI核心类与接口2、Servlet类处理请求的流程创建servlet类的步骤:创建一个命名为TestServlet继承javax.servlet.http.HttpServlet类详情>>
2023-05-30 10:41:22多线程的优势与劣势分别是什么?
多线程是指在同一个程序中,同时运行多个线程,每个线程都可以独立执行不同的任务,相互之间不会干扰。多线程的优势和劣势如下:优势:提高程序...详情>>
2023-05-30 10:32:12设计模式之生产者与消费者的代码实现
本文主要讲述生产者和消费者模式,文中会使用通俗易懂的案例,使你更好地学习本章知识点并理解原理,做到有道无术。什么是生产者和消费者模式生...详情>>
2023-05-30 10:25:46从零开始学Java之interface接口
一.接口简介简介Java中的接口(interface)类似于是一种特殊的抽象类,它也是众多抽象方法的集合。接口的定义方式、组成部分都与抽象类相似,却比...详情>>
2023-05-29 11:26:17热门推荐
如何进行mysql数据备份?
沸什么是servlet的生命周期?servlet请求处理流程是怎样的?
热servlet底层原理是什么?
热怎样编写java程序?
新多线程的优势与劣势分别是什么?
ssm框架的作用与原理是什么?
设计模式之生产者与消费者的代码实现
接口和抽象类有什么区别?4个方面对比
从零开始学Java之interface接口
从零开始学Java之Java中的内部类是怎么回事?
一分钟带你了解MySQL——基础与介绍
在java中,super关键字怎样使用
什么是事件流以及事件流的传播机制 ?
弹性盒有哪些属性是在父元素身上?