Promise为什么比setTimeout先执行?

emmmm…遇到一题目,promise为什么比setTimeout先执行,查阅了很多文档基本都是说了事件循环的大概的理念,都没有根据事件循环的概念深入解释promise比setTimeout先执行的原因。实在不太喜欢半吊子的解释,也有可能是自己理解不太透彻,简单的整理下原因。

    setTimeout(function(){console.log(1)},0);
    new Promise(function(resolve){
    console.log(2)
    for( var i=0 ; i<10000 ; i++ ){
        i==9999 && resolve()//如果把resolve去掉,就一直处于pending状态
     }
      console.log(3)
    }).then(function(){
      console.log(4)
    });
    console.log(5);
// 这的问题是,为什么答案是 2 3 5 4 1

额,快下班了,我就长话短说吧,今天面试官问我为什么这样,心里想不就是这样么,js单线程,会同步先运行,异步的都放任务队列里,等同步走完了再从任务队列依次提取事件执行。

但问题是promise为什么先比setTimeout先执行呀?

事件循环

接下来说说事件循环吧(Event Loop),先上图
在这里插入图片描述
1、Javascript是单线程的,所有的同步任务都会在主线程中执行。
2、当主线程中的任务,都执行完之后,系统会“依次”读取任务队列里的事件。与之相对应的异步任务进入主线程,开始执行。
3、异步任务之间,会存在差异,所以它们执行的优先级也会有区别。大致分为微任务(micro task,如:Promise、MutationObserver等)和宏任务(macro task或callback queue,如:setTimeout、setInterval、I/O等)。
4、Promise执行器中的代码会被同步调用,但是回调是基于宏任务的。
5、微任务的优先级高于宏任务(这才是根本原因)

6、每一个宏任务执行完毕都必须将当前的微任务队列清空。
7、第一个script标签的代码是第一个宏任务。
8、主线程会不断重复上面的步骤,直到执行完所有任务。

概念解读

1、微观任务执行顺序始终先于宏观任务,并且每个宏观任务可以包含多个微观任务

2、宏观任务保存在“任务队列“中,微观任务保存在微任务的队列中,事件循环其实也就是不断执行宏观任务
3、微任务优先级高的根本原因是执行Loop时会优先检查微任务队列,清空后再去检查宏任务执行队列

以上纯属个人理解,不正确的地方还望各位看官指出,大恩不言谢

执行流程
  • 所有的代码都写在script标签中,所以读取所有代码是第一个宏任务,我们开始执行第一个宏任务。
  • 我们首先遇到setTimeout,他是第二个宏任务,将它扔进宏任务事件队列里先排队。
  • 下来我们遇到promise, promise执行器里的代码会被同步调用,所以我们依次打印出2和3
  • 下来我们接着打印出5,然后执行微任务并且打印出4
  • 我们第一个宏任务执行完毕,执行下一个宏任务,打印出1,到此,所有任务都执行完毕。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值