千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:重庆千锋IT培训  >  技术干货  >  JavaScript全解析——事件轮询EventLoop

JavaScript全解析——事件轮询EventLoop

来源:千锋教育
发布人:lxl
时间: 2023-05-15 14:41:04

事件轮询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

如何进行mysql数据备份?

2023-05-30

从零开始学Java之Java中的内部类是怎么回事?

2023-05-29

什么是事件流以及事件流的传播机制 ?

2023-05-29

最新文章NEW

什么是servlet的生命周期?servlet请求处理流程是怎样的?

2023-05-30

在java中,super关键字怎样使用

2023-05-29

什么是JavaScript伪数组?

2023-05-25

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>