宏任务和微任务

我们先来看一道关于宏任务和微任务的一道面试题:
       console.log('start')

        setTimeout(() => {
            console.log('setTimeout')
        }, 0)

        new Promise((resolve) => {
            console.log('promise')
            resolve()
        })
            .then(() => {
                console.log('then1')
            })
            .then(() => {
                console.log('then2')
            })

        console.log('end')

试问一下上面代码的执行顺序是啥?难道js不是一行一行执行的?
我有点慌,于是我粘贴到浏览器去瞅两眼:

结果为:
start
promise
end
then1
then2
setTimeout

这个就涉及到JavaScript事件轮询中的宏任务和微任务。那么,首先,我们需要先知道JS运行机制。

关于JavaScript

JavaScript是一门单线程语言,即一次只能完成一个任务,若有多个任务要执行,则必须排队按照队列来执行(前一个任务完成,再执行下一个任务)。

  1. JS是单线程执行:指的是JS 引擎线程。
  2. 宿主环境:JS运行的环境。一般为浏览器或者Node。
  3. 执行栈:是一个存储函数调用的栈结构,遵循先进后出的原则。

JavaScript事件循环

  1. 既然js是单线程,那就像只有一个收银台的大超市,人们需要排队一个一个结账,同理js任务也要一个一个顺序执行。这种模式执行简单,但随着日后的需求,事务,请求增多,这种单线程模式执行效率必定低下。只要有一个任务执行消耗了很长时间,在这个时间里后面的任务无法执行。
  2. 常见的有新闻类网站包含的超清图片加载很慢,难道我们的网页要一直卡着直到图片完全显示出来?为了解决这个问题,JavaScript语言将任务执行模式分成同步和异步:
    • 同步模式: 就是上面所说的一种执行模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。
    • 异步模式: 就是每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

在这里插入图片描述

宏任务和微任务

ES6 规范中,microtask 称为 jobs,macrotask 称为 task
宏任务是由宿主发起的,而微任务由JavaScript自身发起。

宏任务(macrotask)包括

  1. script整体代码
  2. setTimeout
  3. setInterval
  4. setImmediate
  5. Ajax
  6. DOM事件

微任务(microtask)包括

  1. process.nextTick
  2. MutationObserve
  3. Promise.then catch finally

微任务比宏任务的执行时间要早

宏任务和微任务执行的顺序
  1. 因为微任务不需要执行上下文(这里指的是资源的切换),所以它可以在一次上下文切换间隔中把所有的微任务都做掉。
  2. 而宏任务因为需要切换上下文,所以他会慢点执行。
  3. 所以会先执行已注册的微任务,然后是宏任务、
  4. 这样,就相当于做了一次上下文的切换,如果在此期间,又有新的微任务或宏任务被注册了,就不断重复上面的这个流程。

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值