0
点赞
收藏
分享

微信扫一扫

javascript系统系列:浅析js中的浏览器循环事件(eventLoop)

大家好,我是前端岚枫,今天主要跟大家分享我整理的浏览器事件循环eventLoop相关:eventloop, 微任务、宏任务等,此方面内容在我们的工作中常用到, 也是大厂面试经常提问的问题,希望下面文章对大家有所帮助。

event loop

event loop就是异步回调的实现原理

  • 同步代码,一行一行放在Call Stack 执行
  • 遇到异步,会先“记录”下,等待时机(定时、网络请求等)
  • 时机到了,就移动到Callback Queue
  • 如Call Stack为空(即同步代码执行完)Event Loop开始工作
  • 轮询查找Callback Queue ,如有则移动到Call Stack 执行
  • 然后继续轮询查找(永动机一样)

1. 浏览器的进程

  • 每一个页卡都是进程(互不影响)
  • 浏览器也有一个主进程(用户界面)
  • 渲染进程 每个页卡里 都有一个渲染进程(浏览器内核)
  • 网络进度(处理请求)
  • GPU进程 3d绘制
  • 第三方插件的进程

进程是计算机调度基本单位

2. 渲染进程(包含着多个线程)

  • GUI渲染进程(渲染页面的)
  • js引擎线程,他和也门渲染时互斥
  • 事件触发线程,独立的线程 EventLoop
  • DOM事件也使用回调,基于event loop,事件click、setTimeout、ajax也是一个独立线程

3. 宏任务、微任务

  • 宏任务 宿主环境提供的异步方法 都是宏任务 script 、ui 渲染、setTimeout , setInterval , Ajax,DOM事件
  • 微任务 语言标准提供promise async/await mutationObserver
  • 微任务执行时机比宏任务要早


javascript系统系列:浅析js中的浏览器循环事件(eventLoop)_微任务

document.body.style.background = 'blue'
console.log(1)
setTimeout(()=>{
console.log(2)
document.body.style.background = 'red'
},0)
console.log(3)
// es6内部是一个微任务
Promise.resolve().then(()=>{
console.log('Promise1')
setTimeout(()=>{
console.log('setTimeout2')
})
})
setTimeout(()=>{
console.log('setTimeout1')
Promise.resolve().then(()=>{
console.log('Promise2')
})
}, 0)
// Promise1
// setTimeout1
// Promise2
//setTimeout2
//async 返回的是一个promise generator +co
// await => yield 如果产出的是一个promise会调用这个promise.then方法
async function async1(){
console.log('async1 start')
//浏览器识别async + await await后面跟的是promise的话默认就会直接调用这个promise的then方法
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2');
}
console.log('script start')
setTimeout(()=>{
console.log('setTimeout')
}, 0)
async1();
new Promise(function(resolve){
console.log('promise1')
resolve()
}).then(function(){
console.log('promise2')
})
console.log('script end')


/**
默认执行 script start ,async1 start
微任务队列【async1 end, promise2】
宏任务队列 【 setTimeout】
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
**/

4. event loop和 DOM渲染

  • 再次回归一遍event loop的过程
  • JS是单线程的,而且和DOM渲染共用一个线程
  • JS执行的时候,得留一些时机供DOM渲染
  • 每次Call Stack清空(即每次轮询结束),即同步任务执行完
  • 都是DOM重新渲染的机会,DOM结构如有改变则重新渲染
  • 然后再去触发下一次Event Loop

◆ 宏任务:DOM渲染后触发,如setTimeout
◆ 微任务: DOM渲染前触发,如Promise

原因

  • 微任务是ES6语法规定的
  • 宏任务是由浏览器规定的
    关注公众号:程序员石磊


举报

相关推荐

0 条评论