前端不可不知的 Event loop

javascript是一门非阻塞单线程语言,执行js代码时,会创造一个执行环境,也就是执行上下文,不了解这部分的可以看一下这一篇博客
js基础 执行上下文栈

遇到异步任务的时候,会挂起,放到task队列中,等同步代码执行完毕后再回过头执行task中的任务。

console.log('script start')

setTimeout(function() {
  console.log('setTimeout')
}, 0)

console.log('script end')
/*
output: script start---> script end ---> setTimeout
*/

虽然延时器设定时间为0,但是因为它是一个异步任务,所以依然按照上面的步骤执行,而且setTimeout默认的最小延迟时间为4ms,如果不足会自动补上。

微任务 宏任务

不同的任务源会被分配到不同的task中去,任务源可以分为微任务(microtask)成为 jobs 和 宏任务(macrotask)成为 task

  • microtastk包括:process.nextTickpromiseObject.observeMutationObserver
  • macrotastk包括:script setTimeout,setInterval,setImmediate,I/O,UIRendering
console.log('script start')

setTimeout(function() {
  console.log('setTimeout')
}, 0)

new Promise(resolve => {
  console.log('Promise')
  resolve()
})
  .then(function() {
    console.log('promise1')
  })
  .then(function() {
    console.log('promise2')
  })

console.log('script end')
// script start => Promise => script end => promise1 => promise2 => setTimeout

很多人有个误区,认为微任务快于宏任务,其实是错误的。因为宏任务中包括了 script ,浏览器会先执行一个宏任务,接下来有异步代码的话就先执行微任务。

所以正确的一次 Event loop 顺序是这样的

  • 执行同步代码,这属于宏任务
  • 执行栈为空,查询是否有微任务需要执行
  • 执行所有微任务
  • 必要的话渲染 UI
  • 然后开始下一轮 Event loop,执行宏任务中的异步代码

通过上述的 Event loop 顺序可知,如果宏任务中的异步代码有大量的计算并且需要操作 DOM 的话,为了更快的 界面响应,我们可以把操作 DOM 放入微任务中

Node中的Event loop

Node 的 Event loop 分为 6 个阶段,它们会按照顺序反复运行

┌───────────────────────┐
┌─>│        timers         │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     I/O callbacks     │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     idle, prepare     │
│  └──────────┬────────────┘      ┌───────────────┐
│  ┌──────────┴────────────┐      │   incoming:   │
│  │         poll          │<──connections───     │
│  └──────────┬────────────┘      │   data, etc.  │
│  ┌──────────┴────────────┐      └───────────────┘
│  │        check          │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
└──┤    close callbacks    │
   └───────────────────────┘

参考链接 https://www.yuchengkai.cn/docs/frontend/browser.html#event-loop

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值