EventLoop 事件循环机制?

文章详细阐述了JavaScript的事件循环机制,包括JS的执行顺序,同步与异步代码的处理,以及微任务和宏任务的区别。事件循环使得JS能够依次执行任务,避免阻塞。在NodeJS中,EventLoop分为6个阶段,并且与浏览器环境下的EventLoop在处理microtask上有差异。文章总结了浏览器和Node中microtask的执行时机不同。
摘要由CSDN通过智能技术生成

目录

一、什么是事件循环机制?

1.JS的执行过程?

2.执行顺序图解

3.事件循环是什么

二、JS的执行顺序是什么?

三、事件循环的执行过程?

四、微任务和宏任务的根本区别

五、事件循环的整体流程

六、NodeJS的Event Loop

Node的Event loop一共分为6个阶段:

Node 与浏览器的 Event Loop 差异:

总结:


一、什么是事件循环机制?

概念:Event Loop就是事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。

1.JS的执行过程?

看下下面这段代码的执行顺序

正确的执行顺序应该是序号111,333,222

   console.log('111'); //第一个被打印出

    setTimeout(() => {
      console.log('222')
    })   //第三个被打印出
    
    console.log('333')  //第二个被打印出

 EventLoop 事件循环机制的实现流程?

实现原因是JS引擎指向代码是自上而下执行的,并且先实行同步代码在执行异步代码。

所以首先会执行序号111这个语句,JS引擎会将这个语句放在调用栈当中,然后执行代码,将序号111打印在控制台当中,当这段代码执行完毕之后,便将这段代码从调用栈中移出去。

然后开始执行后续的代码,此时setTimeout这段代码进入调用栈,这段代码,会调用Web API,2秒之后进入callback队列,此时JS引擎将setTimeout移出调用栈,继续执行后面的代码,所以屏幕上会先打印出序号1,3,此时eventLoop登场了,它会不断循环的访问callbackqueue(回调队列),等2s之后Web API会将要执行的打印序号2这句话放入callbackqueue,eventLoop将callbackQueue中的内容放入调用栈,开始执行,然后屏幕上打印出序号2,这就是eventLoop的基本流程。

2.执行顺序图解

3.事件循环是什么

JS的运行机制就是事件循环

二、JS的执行顺序是什么?

  1. JS是从上到下一行一行执行。
  2. 如果某一行执行报错,则停止执行下面的代码。
  3. 先执行同步代码,再执行异步代码

三、事件循环的执行过程?

  • 同步代码,调用栈执行后直接出栈
  • 异步代码,放到Web API中,等待时机,等合适的时候放入回调队列(callbackQueue),等到调用栈空时eventLoop开始工作
  • 微任务执行时机比宏任务要早
  • 微任务在DOM渲染前触发,宏任务在DOM渲染后触发
    console.log('111'); //第一个被打印

    setTimeout(() => {
      console.log('222')  //第四个被打印
    })

    Promise.resolve().then(() => {  //第三个被打印
      console.log('444')
    })

    console.log('333') //第二个被打印

四、微任务和宏任务的根本区别

宏任务: setTimeout,setlnterval,Ajax,DOM事件,

  • 宏任务是由浏览器规定的

微任务:Promise ,async/await

  • 微任务是由ES6语法规定的

微任务执行时机比宏任务要早 (先记住)

五、事件循环的整体流程

  1. 先清空call stack(调用栈)中的同步代码
  2. 执行微任务队列中的微任务
  3. 尝试DOM渲染
  4. 触发Event Loop反复询问callbackQueue(回调队列)中是否有要执行的语句,有则放入call back继续执行

微任务的执行过程:

  • 设置microtask(微任务)检查点标志为true。
  • 当事件循环microtask执行不为空时:选择一个最先进入的microtask队列的microtask,将事件循环的microtask设置为已选择的microtask,运行microtask,将已经执行完成的microtask为null,移出microtask中的microtask。
  • 清理IndexDB事务
  • 设置进入microtask检查点的标志为false。

六、NodeJS的Event Loop

Node中的 Event Loop是基于libuv实现的,而libuv是 Node 的新跨平台抽象层,libuv使用异步,事件驱动的编程方式,核心是提供i/o的事件循环和异步回调。libuv的API包含有时间,非阻塞的网络,异步文件操作,子进程等等。 Event Loop就是在libuv中实现的。

NodeEvent loop一共分为6个阶段:

  • timers: 执行setTimeout和setInterval中到期的callback。
  • pending callback: 上一轮循环中少数的callback会放在这一阶段执行。
  • idle, prepare: 仅在内部使用。
  • poll: 最重要的阶段,执行pending callback,在适当的情况下回阻塞在这个阶段。
  • check: 执行setImmediate(setImmediate()是将事件插入到事件队列尾部,主线程和事件队列的函数执行完成之后立即执行setImmediate指定的回调函数)的callback。
  • close callbacks: 执行close事件的callback,例如socket.on('close'[,fn])或者http.server.on('close, fn)。
     

Node 与浏览器的 Event Loop 差异:

浏览器环境下,microtask 的任务队列是每个 macrotask 执行完之后执行。而在 Node.js 中,microtask 会在事件循环的各个阶段之间执行,也就是一个阶段执行完毕,就会去执行 microtask 队列的任务。

总结:

浏览器和 Node 环境下,microtask 任务队列的执行时机不同

  • Node 端,microtask 在事件循环的各个阶段之间执行
  • 浏览器端,microtask 在事件循环的 macrotask 执行完之后执行
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值