深入理解js执行机制

  1. JS为什么是单线程的?

JS最初被设计用在浏览器中,那么想象一下,如果浏览器中的JS是多线程的。

场景描述:
那么现在有2个线程,process1 process2,由于是多线程的JS,所以他们对同一个dom,同时进行操作
process1 删除了该dom,而process2 编辑了该dom,同时下达2个矛盾的命令,浏览器究竟该如何执行呢?

这样想,JS为什么被设计成单线程应该就容易理解了吧。

  1. JS为什么需要异步?

场景描述:
如果JS中不存在异步,只能自上而下执行,如果上一行解析时间很长,那么下面的代码就会被阻塞。
对于用户而言,阻塞就意味着"卡死",这样就导致了很差的用户体验

  1. JS单线程又是如何实现异步的呢?

其实本质就是通过js的事件循环来实现的,也可以将此理解为js的执行机制

二、事件循环(Event Loop)

备注:js代码可以有两种分类,一种是分为同步代码和异步代码,还有一种更为精确的分类是分为宏任务和微任务,今天我们要讲的就是后一种。。。

刚提到了宏任务和微任务,那么哪些代码属于宏任务?哪些属于微任务呢?

宏任务:包括整体代码script,setTimeout,setInterval
微任务:Promise(then语句),process.nextTick

js的执行机制是:

  • 开始执行js代码是,就是执行第一个宏任务,因为js代码就属于宏任务,然后按从上往下的顺序依次执行下去,当遇到像刚才提到的setTimeout,setInterval时,就会暂时先将他们整体的代码先放到宏任务的【事件队列】中,如果期间遇到像Promise(then语句),process.nextTick等微任务时,就将其放到微任务的【事件队列】里;
  • 当前第一个宏任务执行完成后(js代码从上往下执行过一边,同步代码被执行完了,宏任务和微任务都被放到了各自的事件队列中),此时会查看微任务的【事件队列】,并将里面全部的微任务依次执行完,此时算是第一轮事件循环结束了。
    在这里插入图片描述

总结:就是执行一个宏任务,把所有微任务执行完算一个循环,重复以上两个步骤,这就是js的事件循环,理解一点了吗?

好,接下来讲完了理论知识,我们就来进行一些实战练习,看一些例子巩固下:

Demo1:

 console.log(1)
    
 setTimeout(function(){
        console.log(2)
    },0)

 console.log(3)      //运行结果是:1,3,2

代码解析:

这个例子中,当执行第一句代码时,就进行了第一个宏任务的执行(普通js代码),所以按顺序从上往下执行,首先输出1,然后遇到setTimeout,将该段代码先暂时放到宏任务的事件队列中,然后接着往下执行,输出3,当第一轮的宏任务执行完成后,会去微任务的事件队列中去寻找有没有要执行的代码,很明显,此时没有,所以第一轮的事件循环结束,开始第二轮的事件循环,执行第二个宏任务(也就是刚才的setTimeout),于是最后输出的就是2,所以最终结果就是1,3,2

Demo2:

setTimeout(function(){
     console.log('1')
 });
 
 new Promise(function(resolve){
     console.log('2');
     for(var i = 0; i < 10000; i++){
         i == 99 && resolve();
     }
 }).then(function(){
     console.log('3')
 });
 
 console.log('4');

代码解析:
这个例子中,同样也是一开始执行js代码时(第一个宏任务),遇到setTimeout,将其放至宏任务的事件队列中,Promise函数中的代码是同步立即执行的,所以此时第一个输出的是2,然后执行到then语句时,它属于微任务,所以将其放到微任务的事件队列中,遇到console.log(4)同步代码也是立即执行,到这第一个宏任务执行完成了,然后去微任务事件队列中去寻找有没有要执行的代码,也就是刚才的then语句,于是输出3,此时第一轮的事件循环结束了,开始执行第二个宏任务(setTimeout代码),于是输出1,所以最终这段代码的输出结果是2,4,3,1

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ronychen’s blog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值