【下馆子版】 微任务、宏任务、Event Loop
同步
写了这么久的js,当然知道js是单线程,代码出现阻塞就会影响后面的代码执行
执行alter()
不去处理alter()
执行结果,后面代码是不会继续执行.当然一些
暴力方式也会将页面进入一种假死状态.因为js线程一直等待函数执行完成.
异步
解决阻塞衍生的就是"异步"的概念
主题
当你去"东北菜馆"点菜(调用栈),前面客人点完菜
服务员下单完成,就轮到对你服,务询问你吃啥子,服务确认你的需求就会将下单内容发送至后厨,(异步的概念就体现出来了)
服务员就是"主线程"(mian)执行同步函数,而厨师就是处理异步任务函数,点菜就是确认是同步还是
异步,这里细节分析一点就是,当我们需要的是哪个啤酒,来套碗筷就是同步函数,服务员就可以
帮助我们完成.而炒菜不是主线程(服务员)的操作范围,她只需要将异步函数交予消息队列(厨师/厨房)
等待消息队列(厨师)完成菜品,会有打盒交由服务员,这一过程就是将异步结果交由主线程.
这个过程可以就是我们理解弹出任务队列到调用栈,而Event Loop
这一行为可以理解为:
当服务员完成下单、拿碗筷等同步工作、需要监听打盒传出的菜品,并上菜.
但是在周末,小情侣的出没,厨师的压力会非常的大,会有一些比较复杂的菜品出现eg:水煮鱼、
霸王别姬啊、金勾钓鱼、这些菜太麻烦了,为了让其他菜品快速出菜,厨师就将菜品分为俩类
一类是容易做的(微任务)另一类是难做的(宏任务),先去处理容易菜品,再去处理复杂的菜品
因为这一分类大大加快了出菜的速度,所以一直被沿用.
哇哇哇都看到这里了,相信你去点菜就很了解整个点菜出菜和需要筷子都去找谁,明白你的菜为啥那么慢了把*
不要问:问就是我在后厨干过.
当然分别菜品做饭难以是在厨师确认的。我们尝试也了解,微任务就是雪山盖顶一类、宏任务就是霸王别姬.
雪山盖顶:
霸王别姬
拉回来
总结
js线程执行碰到异步函数,就会将异步函数,存放值消息队列,继续执行异步函数后的代码,碰到异步代码
往复前面的步骤.完成同步代码的执行。再去执行消息队列的函数,执行消息队列优先去执行微任务,执行完成一个微任务,确认是否还有未
执行的微任务,有则继续执行微任务,无则执行宏任务往复的过程称为Event Loop
消息队列中函数执行结果依然是异步函数,确认微任务、宏任务、并添加至对应队列末尾.(插队不是好习惯)
微任务类型
宏任务类型
Event Loop
简单说就是一个监听装置,检查调用栈是否为空,便会从消息队列弹出一个回调放入调用栈执行(优先是微任务)
确认微任务执行完毕,才去调用宏任务.Event Loop就是判断 调用栈为空,与消息队列是否存在微任务函数,
确认微任务不存在,宏任务弹出到调用栈执行.
下图就是完成显示整个js代码执行过程.
有了上面经验整点白的,干喝啤的没劲,上题:
(1)花生,鸡腿摆上…
setTimeout(function() {
console.log("settimeMess")
}, 0)
for(let i=0; i<10000; i++) {}
console.log("forMess")
// output forMess settimeMess
(2)换个大一点容器
console.log('111');
(async ()=>{
console.log(333);
})().then(()=>{
console.log(444);
});
console.log('222');
//output 111 333 222 444
(3)别拿碗了,直接把盆拿过来,瓶子口太小了
console.log('111');
(async ()=>{
console.log(333);
await console.log(444);
console.log(555);
})().then(()=>{
console.log(666);
});
console.log('222');
//output 111 333 555 444 222 666
(4)厕所在哪???
console.log('111');
setTimeout(()=>console.log('222'), 0);
(async ()=>{
console.log(333);
await console.log(444);
console.log(555);
setTimeout(()=>console.log('666'), 0);
})().then(()=>{
console.log(777);
});
console.log('888');
//output 111 333 444 888 555 777 222 666
- 点赞
- 收藏
- 关注作者
评论(0)