JS运行原理,宏任务微任务的任务loop驱动模式

要拎清运行原理,就要知道js有什么无理限制和主要解决什么问题
首先,js是单线程的,不能开辟多线程。
这决定了它支持并发,不支持并行

「并发」强调的是可以一起「出『发』」,「并行」强调的是可以一起「执『行』」
你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。
你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。

既然能并发,解决通信问题的时候就可以利用异步充分利用等待时间。
假设用户要处理10个请求,并且等到以后瞬间处理完,第一个等100秒,后面的每个等10秒。
如果按顺序,就是等190秒(同步)
更好的方法是发出10个请求,哪个先回来先处理哪个,只要100秒(异步)

老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)
老张觉得自己有点傻
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)
老张觉得这样傻等意义不大
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
老张觉得自己聪明了。
所谓同步异步,只是对于水壶而言。
普通水壶,同步;响水壶,异步。
虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。
同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。
所谓阻塞非阻塞,仅仅对于老张而言。
立等的老张,阻塞;看电视的老张,非阻塞。
情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。

因此,这个执行逻辑是:
1把需要等待的都放到一个地方(管道/队列),先干那些不用等的
2不用等的干完了后,干那些完成等待的

但是还有可以优化的地方,目前这样只要是等待的就各凭本事,看谁先好。但是更多时候我们是有一个特殊要求的,得先等某个先好,等待之间也有先后的优先级关系。(譬如得等页面初始化数据得到以后,利用这些数据再做别的请求,不然没初始数据)
为了区分优先级关系,分出来宏任务、微任务。优先级高的叫微任务,反则反之。

因此执行逻辑变为:
1把需要等待的区分成宏任务微任务放到两个不同地方(管道/队列),先干不用等的
2不用等的干完了后,干那些微任务
3当前没有微任务了,干那些宏任务

JS运行原理,宏任务微任务的任务loop驱动模式
JS运行原理,宏任务微任务的任务loop驱动模式

用实例:

setTimeout(_ => console.log(4))

new Promise(resolve => {
  resolve()
  console.log(1)
}).then(_ => {
  console.log(3)
})

console.log(2)

打比方:
去电信营业厅换号码,干三件事
1.填表办新卡
2.填表注销卡(注销之前都要取消套餐)
3.有积分就先把积分花了
(要填表=要等待)

填表办新卡(4)//宏任务

取消套餐(1)
then 
填表注销卡(3)//微任务

花积分(2)
上一篇:Event Loop


下一篇:基于keil5下STM32的C与汇编语言混合编程