海星吧的面试宝典:关于js中微、宏任务队列面试题的理解。

海星吧 2023-2-19 5462

halo,新年已经过去了,现在也是马上到金三银四的阶段,我要去广州找工作了。

准备刷面试题的时候对任务队列这块还不是很透彻,答题的时候一直打错,不过现在也终于理解了。

js中的异步任务分别是微任务和宏任务。

那么什么是微任务和宏任务呢?

async function async1() {
    console.log('async1 start'); // 2 同步任务
    await async2();
    console.log('async1 end'); // 6 微任务
}
async function async2() {
    console.log('async2'); // 3  同步任务
}
console.log('script start');  // 1 同步任务
setTimeout(() => {
    console.log('setTimeout'); 8 宏任务
}, 0);
async1(); // =>
new Promise(function (resolve) {
    console.log('promise1'); // 4 同步任务
    resolve();
}).then(function () {
    console.log('promise2');  // 7 微任务
});
console.log('script end'); // 5 同步任务

看看上面这些代码的执行顺序吧。

js是先执行同步任务之后才到微任务,最后是宏任务,

而在Pormise中,其回调函数里的代码是同步执行的,Pormise.then函数却是异步执行的微任务。

setTimeout是最没地位的,一定是在then之后才执行的宏任务,所以就算它被放在了上面,也得老老实实排最末去。

那么问题来了,照我这么说,setTimeout里嵌套Promise的话,也是Promise里的先执行?

这还是得给面子的,人家毕竟是Function,肯定也有同步任务和异步任务嘛。

来看这个。

console.log('==== start ====') // 1 一级 同步任务

setTimeout(function () {
    console.log('定时器') // 5 二级 同步任务

    setTimeout(function () {
        console.log('定时器中的定时器') // 8 三级 宏任务
    },0)

    new Promise(function (resolve) {// 微任务
        console.log('准备执行 for 循环111') // 6 二级  微任务

        for (let i = 0; i < 666; i++) {
            i == 5 && resolve()
        }
    }).then(function () {
        console.log('执行了 then 方法1111') // 7 二级 微任务
    })

}, 0)

console.log('==== end ====') // 2  一级 同步任务

new Promise(function (resolve) {
    console.log('准备执行 for 循环222') // 3  一级  同步任务

    for (let i = 0; i < 666; i++) {
        i == 5 && resolve()
    }
}).then(function () {
    console.log('执行了 then 方法2222') // 4  一级  微任务
})

上面用了一个setTimeout嵌套Promise的题目。

看看,其实还是先执行同步任务,再执行微任务,setTimeout没地位排老末。

但是不能挡着人家生崽啊,崽子有出息没出息,一眼就看出来了。

嵌套之后的代码,再次投入任务队列中,但一定是在一级之后,等一级的部分执行完,才会执行二级、三级的。

现在对这种类型的面试题能够理解了吧。

下面给你们一道面试题自己做做吧。

console.log(1)
setTimeout(function() {
  console.log(2)
  new Promise(function(resolve) {
    console.log(3)
    resolve()
  }).then(function() {
    console.log(4)
  })
},0)
 
new Promise(function(resolve) {
  console.log(5)
  resolve()
}).then(function() {
  console.log(6)
})

setTimeout(function() {
  console.log(7)
  new Promise(function(resolve) {
    console.log(8)
    resolve()
  }).then(function() {
    console.log(9)
  })
},0)
console.log(10)

实在答不出可以把代码复制一下去开发者工具里运行看看。

我是海星吧,有兴趣的可以点赞、评论加关注(如果有关注功能的话)。

感谢支持,我们下次再见。


我是傻逼!!!

之前上面的都是错的,同步任务是同步任务,异步任务分为微任务和宏任务,

同步任务放在主线程执行,异步任务放在任务队列中执行,

同步任务执行完成之后才会去调用异步任务的微任务和宏任务,

而微任务一定在宏任务之前触发完成后才会去调用宏任务,

辨别微任务:Promise,async&await,process.nextTick, Object.observe, MutationObserver。

宏任务:setTimeout,setInterval,setImmediate,I/O, UI rendering

Promise的回调函数里的是同步任务,then、catch是微任务

这个精华帖真的是特么得的丢脸。

现在大致上是改好了。

最后于 2023-3-7 被海星吧编辑 ,原因: 帖子讲解的有错误、错的离谱,现在改好。
弱鸡程序员年底还在加班
最新回复 (2)
  • 海星吧 2023-2-19
    0 2
    喀秋莎 所以海星你能开发黄油吗?
    No。。
    弱鸡程序员年底还在加班
  • 海星吧 2023-2-21
    0 3
    欧派兽 奖三
    感谢感谢
    弱鸡程序员年底还在加班
    • ACG里世界
      4
          
返回
发新帖