【下馆子版】 微任务、宏任务、Event Loop

举报
窗台 发表于 2022/02/13 17:16:14 2022/02/13
【摘要】 下完馆子,你还是不懂什么是异步、什么微任务、宏任务、Event Loop 来找我,我带你去东北菜馆走一遍流程.

同步

写了这么久的js,当然知道js是单线程,代码出现阻塞就会影响后面的代码执行
执行alter()不去处理alter()执行结果,后面代码是不会继续执行.当然一些
暴力方式也会将页面进入一种假死状态.因为js线程一直等待函数执行完成.

异步

解决阻塞衍生的就是"异步"的概念
主题
image.png

当你去"东北菜馆"点菜(调用栈),前面客人点完菜
服务员下单完成,就轮到对你服,务询问你吃啥子,服务确认你的需求就会将下单内容发送至后厨,(异步的概念就体现出来了)
服务员就是"主线程"(mian)执行同步函数,而厨师就是处理异步任务函数,点菜就是确认是同步还是
异步,这里细节分析一点就是,当我们需要的是哪个啤酒,来套碗筷就是同步函数,服务员就可以
帮助我们完成.而炒菜不是主线程(服务员)的操作范围,她只需要将异步函数交予消息队列(厨师/厨房)
等待消息队列(厨师)完成菜品,会有打盒交由服务员,这一过程就是将异步结果交由主线程.
这个过程可以就是我们理解弹出任务队列到调用栈,而Event Loop 这一行为可以理解为:
当服务员完成下单、拿碗筷等同步工作、需要监听打盒传出的菜品,并上菜.
但是在周末,小情侣的出没,厨师的压力会非常的大,会有一些比较复杂的菜品出现eg:水煮鱼、
霸王别姬啊、金勾钓鱼、这些菜太麻烦了,为了让其他菜品快速出菜,厨师就将菜品分为俩类
一类是容易做的(微任务)另一类是难做的(宏任务),先去处理容易菜品,再去处理复杂的菜品
因为这一分类大大加快了出菜的速度,所以一直被沿用.

哇哇哇都看到这里了,相信你去点菜就很了解整个点菜出菜和需要筷子都去找谁,明白你的菜为啥那么慢了把*
不要问:问就是我在后厨干过.
image.png
当然分别菜品做饭难以是在厨师确认的。我们尝试也了解,微任务就是雪山盖顶一类、宏任务就是霸王别姬.

雪山盖顶:
image.png

霸王别姬
image.png


拉回来

总结

js线程执行碰到异步函数,就会将异步函数,存放值消息队列,继续执行异步函数后的代码,碰到异步代码
往复前面的步骤.完成同步代码的执行。再去执行消息队列的函数,执行消息队列优先去执行微任务,执行完成一个微任务,确认是否还有未
执行的微任务,有则继续执行微任务,无则执行宏任务往复的过程称为Event Loop
消息队列中函数执行结果依然是异步函数,确认微任务、宏任务、并添加至对应队列末尾.(插队不是好习惯)

微任务类型
image.png

宏任务类型
image.png

Event Loop
简单说就是一个监听装置,检查调用栈是否为空,便会从消息队列弹出一个回调放入调用栈执行(优先是微任务)
确认微任务执行完毕,才去调用宏任务.Event Loop就是判断 调用栈为空,与消息队列是否存在微任务函数,
确认微任务不存在,宏任务弹出到调用栈执行.
下图就是完成显示整个js代码执行过程.
image.png

有了上面经验整点白的,干喝啤的没劲,上题:

(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
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。