js中的宏任务和微任务以及任务调动的流程

宏任务和微任务和同步代码的执行的流程

执行栈在执行完同步任务后,查看执行栈是否为空,如果执行栈为空,就会去检查微任务(microTask)队列是否为空,如果为空的话,就执行Task(宏任务),否则就一次性执行完所有微任务。
每次单个宏任务执行完毕后,检查微任务(microTask)队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务(microTask)后,设置微任务(microTask)队列为null,然后再执行宏任务,如此循环。
总之,微任务的优先级要比宏任务的优先级高,同步代码会直接放到执行栈执行,优先级可以理解为最高。

宏任务:定时器的两个函数等等。
微任务:promise.then等等。

下面来看这个例子就很好理解了

 		setTimeout(()=>{
            console.log("settimeout running")
            new Promise(resolve=>{
                console.log("settimeout promise running")
                resolve()
            })
            .then(()=>{
                console.log("settimeout promise then running")
            })
        },0)

        new Promise((resolve)=>{
            console.log("promise running")
            resolve("promise then running")
        })
        .then((data)=>{
            console.log(data)
            setTimeout(()=>{
                console.log("promise then settimeout running")
            },0)
        })

        console.log("main running")

小伙伴们可能有点懵,这个执行顺序是什么呢?下面就给大家详细的分析。先来看结果
在这里插入图片描述

先说一点,定时器实际上有一个控制器,时间到了,就把定时器中的函数放到宏任务队列等待执行,我们这里统一设置0ms,所以就直接按放到宏任务队列来说了,但其实还是有控制器的这么一个过程。这个知道就好

      首先从上到下,先将定时器中的部分放到宏任务队列排队等待,promise参数中函数的内容是同步代码,所以 1.输出promise running,同步代码执行后产生了一个异步任务(then中的代码),所以将这个异步任务放到微任务队列排队等待,接下来2.执行同步代码,输出 main running。到这里,最开始的两个同步任务已经执行完成,现在就剩微任务队列中的then,宏任务队列中的定时器。
      我们说微任务的优先级是比宏任务高的,所以先执行then,3.输出 promise then running,输出之后这个微任务又产生了一个宏任务,将产生的宏任务放到宏任务队列。此时微任务队列为空了,执行宏任务队列,此时宏任务队列存在刚开始的定时器和刚刚微任务产生的定时器,4.输出 settimeout running,执行之后又产生一个同步代码,5.输出 settimeout promise running,之后又产生一个微任务then,将它放到微任务队列。
      此时,微任务队列中存在任务,又转向执行该微任务,6.输出 settimeout promise then running,执行完之后,最后只剩下一个宏任务,7输出 promise then settimeout running。到这里是不是就理解了呢?是在没明白可以画两个队列和一个执行栈去模拟一下,就很容易理解喽!

再来一段代码,这里混合await

(async () => {
    console.log(1);
    setTimeout(() => {
        console.log(2);
}, 0);
await new Promise((resolve, reject) => {
    console.log(3);
    // resolve()
}).then(() => {
    console.log(4);
});
    console.log(5);
})();

输出是132,这是因为这是立即执行函数,首先执行同步任务输出1,这个没有啥问题,下面产生一个宏任务放到后面,接下来注意await,它会等待promise的执行结果,只有当promise执行成功reject或者resolve并且回调函数都执行完成才会接着执行后续的代码,显然promise中没有resolve,所以then中的代码以及await之后的都不会执行了,接下来就是只有一个宏任务输出2 所以输出132

(async () => {
    console.log(1);
    setTimeout(() => {
        console.log(2);
}, 0);
await new Promise((resolve, reject) => {
    console.log(3);
    resolve()
}).then(() => {
    console.log(4);
});
    console.log(5);
})();

这个就输出的是13452,这就是表示await会等待promise中的所有内容执行完成,包括回调函数全部执行完成之后才会执行后面的部分,其实也就是相当于加了await之后也成了同步代码
如果明白了原理可以看下面博客的应用举例
宏任务微任务应用举例

最后推荐一个博主的视频,讲的很好
哔哩哔哩资源

文章是个人的理解,如有错误之处,还请大佬批评指正,也欢迎大家探讨交流。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程小飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值