event loop

事件轮询(event loop)

含义

event loop即事件轮询,这个是js里面为了解决单线程阻塞问题提出的解决方案,也是js异步执行机制的原理

  • 异步任务执行的顺序又是怎样的呢?这时候我们就需要了解事件轮询机制
    console.log(1)
    setTimeout(()=>{
        console.log(2)
    },0)
    setInterval(() => {
        console.log(3)
    }, 30);
    console.log(4)
    console.log(5)
    new Promise((resolve)=>{
        console.log(6)
        resolve(7)
    }).then(res=>{
        console.log(res)
    })

事件轮询

  • 图示
  • 图解
    1. 首先加载js的时候,整个的script代码会一行一行的执行
    2. 每一行代码执行都会进入调用栈,调用栈是一个执行代码的地方
    3. 调用栈在运行代码的时候会判断这行代码是同步还是异步,如果是同步直接执行返回执行之后得到的结果,如果是异步,会将异步的代码放到webAPI里面,直接执行后面的同步代码
    4. 异步的代码在webAPI里面会等待时机,比如说一个定时器3s执行,在3s到达的时候会将对应的回调函数添加到执行的队列(task queue)里面
    5. 所有的同步代码执行结束之后,此时会开启事件轮询,查看task queue里面是否有任务需要执行,如果有就拿到调用栈执行,一直到所有的task queue任务结束
  • 案例
console.log(1)
setTimeout(function cb(){
    console.log(2)
}, 1000)
console.log(3)
  • 执行过程
    1. console.log(1)进入调用栈 是同步 控制台打印输出 1 结束
    2. setTimeout(cb, 1000) 进入调用栈 是异步, 将cb放入webAPI等待,继续执行下一步代码
    3. console.log(2)进入调用栈 是同步 控制台打印输出 2 结束
    4. 此时调用栈任务执行结束,开启事件轮询
    5. cb函数在一秒钟后进入执行队列(task queue)
    6. cb函数进入调用栈执行,输出 3 结束
  • 点击查看完整代码执行
  • 总结
    • 可以看出所有的同步任务都会在异步任务之前执行
    • 异步任务如果有很多 他们的执行顺序又是如何呢

宏任务和微任务

  • 宏任务:macrotask,setTimeout,setInterval, ajax, dom事件,宏任务是由浏览器提供的
  • 微任务:microtask,promise,async/await,微任务是由es6提供的
  • 为什么要区分宏任务和微任务?
    • 因为宏任务和微任务的执行时机不一样,这样就会导致我们对于异步的代码认识产生理解的误区
  • 执行顺序
    1. js首先会执行调用栈里面同步的代码
    2. 遇到宏任务,会将宏任务的回调函数压入到webapi中等待,合适进入task queue队列等待
    3. 遇到微任务,会将微任务的回调函数压入micro task queue队列中
    4. 调用栈中所有同步代码执行完成,开启event loop,会优先执行micro task queue队列中的回调函数
    5. 微任务执行完成之后,dom进行渲染
    6. dom渲染完成,会执行task queue中的的回调函数
    7. 重复以上步骤
  • 案例演示
console.log(1)
setTimeout(function cb(){
    console.log(2)
}, 0)
new Promise(function handler(resovle){
    resovle(3)
}).then(function(res){
    console.log(res)
})
console.log(4)

微任务执行在DOM渲染之前执行,宏任务执行在DOM渲染之后

<body>
    <h1>页面中的元素</h1>
    <script>
        console.log(1)
        setTimeout(function cb(){
            alert(222)
            console.log(2)
        }, 1000)
        new Promise(function handler(resovle){
            resovle(3)
        }).then(function(res){
            alert(111)
            console.log(res)
        })
        console.log(4)
    </script>
</body>
</html>
      console.log(res)
    })
    console.log(4)
</script>
``` + 弹出alert(111)的弹窗此时页面上h1并没有生成,弹出alert(222)的时候页面h1已经生成,由此证明微任务是在dom渲染之前执行,宏任务是在dom渲染之后执行
  • 41
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦逼的猿宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值