事件循环机制

EventLoop

当js引擎遇到一个异步事件后,其实不会说一直等到异步事件的返回,而是先将异步事件进行挂起。等到异步事件执行完毕后,会被加入到事件队列中。(注意,此时只是异步事件执行完成,其中的回调函数并没有去执行。)当执行队列执行完毕,主线程处于闲置状态时,会去异步队列那抽取最先被推入队列中的异步事件,放入执行栈中,执行其中的回调同步代码。如此反复,这样就形成了一个无限的循环。这就是这个过程被称为“事件循环(Event Loop)”的原因。

微任务与宏任务的区别

这个就像去银行办业务一样,先要取号进行排号。

因为柜员同时职能处理一个来办理业务的客户,这时每一个来办理业务的人就可以认为是银行柜员的一个宏任务来存在的,当柜员处理完当前客户的问题以后,选择接待下一位,广播报号,也就是下一个宏任务的开始。

所以多个宏任务合在一起就可以认为说有一个任务队列在这,里边是当前银行中所有排号的客户。

任务队列中的都是已经完成的异步操作,而不是说注册一个异步任务就会被放在这个任务队列中,就像在银行中排号,如果叫到你的时候你不在,那么你当前的号牌就作废了,柜员会选择直接跳过进行下一个客户的业务处理,等你回来以后还需要重新取号

而且一个宏任务在执行的过程中,是可以添加一些微任务的,就像在柜台办理业务,你前边的一位老大爷可能在存款,在存款这个业务办理完以后,柜员会问老大爷还有没有其他需要办理的业务,这时老大爷想了一下:“最近P2P爆雷有点儿多,是不是要选择稳一些的理财呢”,然后告诉柜员说,要办一些理财的业务,这时候柜员肯定不能告诉老大爷说:“您再上后边取个号去,重新排队”。

所以本来快轮到你来办理业务,会因为老大爷临时添加的“理财业务”而往后推。

也许老大爷在办完理财以后还想再办一个信用卡?或者再买点儿纪念币

无论是什么需求,只要是柜员能够帮她办理的,都会在处理你的业务之前来做这些事情,这些都可以认为是微任务。

这就说明:

在当前的微任务没有执行完成时,是不会执行下一个宏任务的。

setTimeout就是作为宏任务来存在的,而Promise.then则是具有代表性的微任务,上述代码的执行顺序就是按照序号来输出的。

所有会进入的异步都是指的事件回调中的那部分代码

也就是说new Promise在实例化的过程中所执行的代码都是同步进行的,而then中注册的回调才是异步执行的。

在同步代码执行完成后才回去检查是否有异步任务完成,并执行对应的回调,而微任务又会在宏任务之前执行。

本来setTimeout已经先设置了定时器,然后在当前进程中又添加了一些Promise的处理。

所以,即便我们继续在Promise中实例化Promise,其输出依然会早于setTimeout的宏任务

实际情况下很少会有简单的这么调用Promise的,一般都会在里边有其他的异步操作,比如fetch、fs.readFile之类的操作。

而这些其实就相当于注册了一个宏任务,而非是微任务。

Promise的实现可以是微任务,也可以是宏任务,但是普遍的共识表示(至少Chrome是这么做的),Promise应该是属于微任务阵营的

你可能感兴趣的:(事件循环机制)