【JS】这次,十分钟把宏任务和微任务讲清楚

这次,十分钟把宏任务和微任务讲清楚

Peter谭老师发布于 32 分钟前

为什么写这个文章

  • 这是一道大厂、小厂面试官都喜欢问的题目
  • 很多面试官和面试者也不知道什么是标准答案
  • 网上各种文章层次不齐..误导过不少人,包括我
  • 觉得还是今天花十分钟讲清楚他吧

正式开始

  • 先上代码

    function app() {

setTimeout(() => {

console.log("1-1");

Promise.resolve().then(() => {

console.log("2-1");

});

});

console.log("1-2");

Promise.resolve().then(() => {

console.log("1-3");

setTimeout(() => {

console.log("3-1");

});

});

}

app();

  • 输出结果:

1-2

1-3

1-1

2-1

3-1

开始分析

  • 面试官特别喜欢问:你讲讲什么是微任务和宏任务

所谓微任务和宏任务

  • 宏任务:常见的定时器,用户交互事件等等.(宏任务就是特定的这些个任务,没什么特殊含义)
  • 微任务:Promise相关任务,MutationObserver等(一样,只是一种称呼而已!!!

到底先执行微任务还是宏任务

  • 先有鸡还是先有蛋? 到底是先有宏任务还是微任务啊?

第一个原则

  • 万物皆从全局上下文准备退出,全局的同步代码运行结束的这个时机开始
  • 例如我们刚才这段代码:

   function app() {

setTimeout(() => {

console.log("1-1");

Promise.resolve().then(() => {

console.log("2-1");

});

});

console.log("1-2");

Promise.resolve().then(() => {

console.log("1-3");

setTimeout(() => {

console.log("3-1");

});

});

}

app();

  • 当执行完了console.log("1-2");的时候,意味着全局的上下文马上要退出了,因为此时全局的同步代码都执行完了,剩下的都是异步代码

第二个原则

  • 同一层级下(不理解层级,可以先不管,后面会讲),微任务永远比宏任务先执行
  • 即Promise.then比setTimeout先执行
  • 所以先打印1-3,再打印1-1

第三个原则

  • 每个宏任务,都单独关联了一个微任务队列
  • 我用刚买的黑板画了一张图,大家就知道什么是层级了

【JS】这次,十分钟把宏任务和微任务讲清楚

  • 每个层级的宏任务,都对应了他们的微任务队列,微任务队列遵循先进先出的原则,当全局同步代码执行完毕后,就开始执行第一层的任务。同层级的微任务永远先于宏任务执行,并且会在当前层级宏任务结束前全部执行完毕

怎么分辨层级?

  • 属于同一个维度的代码,例如下面的func1和func2就属于同层级任务

setTimeout(func1)...

Promise.resolve().then(func2)...

  • 下面这种fn1和fn2就不属于同一个层级的,因为fn2属于内部这个setTimeout的微任务队列,而fn1属于外部setTimeout的微任务队列

setTimeout(()=>{

Promise.resolve().then(fn1)

setTimeout(()=>{

Promise.resolve().then(fn2)

})})

遇到面试题

  • 就按照我的套路,从全局上下文退出前(全局的同步代码执行完毕后),开始收集当前层级的微任务和宏任务,然后先清空微任务队列,再执行宏任务.如果这期间遇到宏任务/微任务,就像我这样画个图,把他们塞进对应的层级里即可

写在最后

  • 简单的1000字,相信能彻底解决你的微任务和宏任务疑惑
  • 如果你想理解得更深,记得关注下公众号,后续会写一些更深入的东西,真正的“深入浅出”

html5cssjavascript前端node.js

阅读 51发布于 32 分钟前

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议


前端巅峰

注重前端性能优化和前沿技术,重型跨平台开发,即时通讯技术等。 欢迎关注微信公众号:前端巅峰

avatar

Peter谭老师

前端架构师

13.2k 声望

4.3k 粉丝

0 条评论

得票时间

avatar

Peter谭老师

前端架构师

13.2k 声望

4.3k 粉丝

宣传栏

为什么写这个文章

  • 这是一道大厂、小厂面试官都喜欢问的题目
  • 很多面试官和面试者也不知道什么是标准答案
  • 网上各种文章层次不齐..误导过不少人,包括我
  • 觉得还是今天花十分钟讲清楚他吧

正式开始

  • 先上代码

    function app() {

setTimeout(() => {

console.log("1-1");

Promise.resolve().then(() => {

console.log("2-1");

});

});

console.log("1-2");

Promise.resolve().then(() => {

console.log("1-3");

setTimeout(() => {

console.log("3-1");

});

});

}

app();

  • 输出结果:

1-2

1-3

1-1

2-1

3-1

开始分析

  • 面试官特别喜欢问:你讲讲什么是微任务和宏任务

所谓微任务和宏任务

  • 宏任务:常见的定时器,用户交互事件等等.(宏任务就是特定的这些个任务,没什么特殊含义)
  • 微任务:Promise相关任务,MutationObserver等(一样,只是一种称呼而已!!!

到底先执行微任务还是宏任务

  • 先有鸡还是先有蛋? 到底是先有宏任务还是微任务啊?

第一个原则

  • 万物皆从全局上下文准备退出,全局的同步代码运行结束的这个时机开始
  • 例如我们刚才这段代码:

   function app() {

setTimeout(() => {

console.log("1-1");

Promise.resolve().then(() => {

console.log("2-1");

});

});

console.log("1-2");

Promise.resolve().then(() => {

console.log("1-3");

setTimeout(() => {

console.log("3-1");

});

});

}

app();

  • 当执行完了console.log("1-2");的时候,意味着全局的上下文马上要退出了,因为此时全局的同步代码都执行完了,剩下的都是异步代码

第二个原则

  • 同一层级下(不理解层级,可以先不管,后面会讲),微任务永远比宏任务先执行
  • 即Promise.then比setTimeout先执行
  • 所以先打印1-3,再打印1-1

第三个原则

  • 每个宏任务,都单独关联了一个微任务队列
  • 我用刚买的黑板画了一张图,大家就知道什么是层级了

【JS】这次,十分钟把宏任务和微任务讲清楚

  • 每个层级的宏任务,都对应了他们的微任务队列,微任务队列遵循先进先出的原则,当全局同步代码执行完毕后,就开始执行第一层的任务。同层级的微任务永远先于宏任务执行,并且会在当前层级宏任务结束前全部执行完毕

怎么分辨层级?

  • 属于同一个维度的代码,例如下面的func1和func2就属于同层级任务

setTimeout(func1)...

Promise.resolve().then(func2)...

  • 下面这种fn1和fn2就不属于同一个层级的,因为fn2属于内部这个setTimeout的微任务队列,而fn1属于外部setTimeout的微任务队列

setTimeout(()=>{

Promise.resolve().then(fn1)

setTimeout(()=>{

Promise.resolve().then(fn2)

})})

遇到面试题

  • 就按照我的套路,从全局上下文退出前(全局的同步代码执行完毕后),开始收集当前层级的微任务和宏任务,然后先清空微任务队列,再执行宏任务.如果这期间遇到宏任务/微任务,就像我这样画个图,把他们塞进对应的层级里即可

写在最后

  • 简单的1000字,相信能彻底解决你的微任务和宏任务疑惑
  • 如果你想理解得更深,记得关注下公众号,后续会写一些更深入的东西,真正的“深入浅出”

以上是 【JS】这次,十分钟把宏任务和微任务讲清楚 的全部内容, 来源链接: utcz.com/a/106173.html

回到顶部