面试题 - 5 道 Promise 笔试题

面试题 - 5 道 Promise 笔试题


Promise 面试题主要体现在与定时器(setTimeout,setInterval),异步函数 async 等同时存在时其执行顺序。

在做题之前抓住以下要点:

  1. JS 的循环执行机制是先执行宏任务,再执行微任务。然后执行第二个宏任务,微任务。第三个宏任务,微任务,,,以此循环。
  2. 如果宏任务中有微任务,则先执行宏任务,再执行宏任务中的微任务,最后执行第二个宏任务。
  3. 如果宏任务中有宏任务,则先执行宏任务,再执行第二个宏任务,最后执行宏任务中的宏任务。
  4. 如果微任务中有宏任务,则先执行微任务,再执行第二个宏任务,最后执行微任务中的宏任务。
  5. 如果微任务中有微任务,则先执行微任务,再执行微任务中的微任务,再执行第二个宏任务,最后执行微任务中的宏任务。
  6. 宏任务有:script、setTimeout\setInterval 定时器等。
  7. 微任务有:Promise 中的 then 方法、async 函数等。

注:以上定时器的宏任务是基于执行时间相同的情况下。如果时间不同,时间最长的始终最后执行。

详情可以参考文章 JavaScript 事件循环机制(Event Loop)简述

题目1:

先执行宏任务,再执行微任务。接着执行第二个宏任务…

<script>
    setTimeout(()=> {
        console.log("1")
    })
    var pro = new Promise((resolved,rejected)=>{
        console.log("2")
        resolved("3")
    });
    console.log("4")
    pro.then((res)=>{
        console.log(res)
    })
</script>

解析:
以上题目中 script 是一个宏任务,称为宏1。setTimeout 是第二个宏任务,称为宏2。pro.then 是一个微任务,称为 微1

先执行宏1。在 宏1 中。先执行 Promise 中的立即执行函数,执行代码 console.log("2"),打印 2。接着执行同步任务console.log("4"),打印 4。宏1 执行完毕。

接着执行 微1,执行代码 console.log(res) ,打印 3 。

接着执行 宏2,执行代码 console.log("1") ,打印 1 。

结果:2 4 3 1

题目2:

如果宏任务中有微任务…

<script>
    var pro = new Promise((resolved,rejected)=>{
        setTimeout(()=> {
           console.log("2")
           resolved("3")
        })
    });
    console.log("4")
    pro.then((res)=>{
        console.log(res)
    })
    setTimeout(()=> {
        console.log("1");
    })
</script>

解析:
以上题目中 script 是一个宏任务,称为 宏1。立即执行函数 Promise 中 的 setTimeout 是第二个宏任务,称为宏2。在 宏2 中有 resolved 微任务,记为 微1。最后一个 setTimeout 记为 宏3

先执行 宏1。在 宏1 中。执行同步代码 console.log("4") 打印 4。

接着执行 宏2,执行代码 console.log("2") 打印 2。

接着执行 微1 ,执行代码 console.log(res) 打印 3。

最后执行 宏3,执行代码 console.log("1") 打印 1。

结果:4 2 3 1

题目3:

如果宏任务中有宏任务…

<script>
    setTimeout(()=> {
        console.log("1");
        setTimeout(()=> {
           console.log("5")          
        })
    })
    var pro = new Promise((resolved,rejected)=>{
        setTimeout(()=> {
           console.log("2")
           resolved("3")
        })
    });
    console.log("4")
    pro.then((res)=>{
        console.log(res)
    })
</script>

解析:
script 记 宏1,打印 4 就不再赘述了。第一个 setTimeout 记为 宏2,里面的 setTimeout 暂时放着。接下来在 Promise 中有一个 setTimeout 记为 宏3。内部的 resolved 微任务记为 微1。接着在第一个 setTimeout 中的 setTimeout 记为 宏4
执行 宏2,执行代码 console.log("1") 打印 1。
执行 宏3,执行代码 console.log("2") 打印 2。
执行 宏3 中的 微1,执行代码 console.log("3") 打印 3。
执行 宏4,执行代码 console.log("5") 打印 5。

结果:4 1 2 3 5

题目4:

如果微任务中有宏任务…

<script>
    setTimeout(()=> {
        console.log("1")
    })
    var pro = new Promise((resolved,rejected)=>{
        setTimeout(()=> {
           console.log("2");
           resolved("3")
        })
    });
    pro.then((res)=>{
        console.log(res);
        setTimeout(()=> {
           console.log("4")
        })
    })   
     setTimeout(()=> {
        console.log("5")
    })
</script>

解析:
第一个 setTimeout 记为 宏2,接下来在 Promise 中有一个 setTimeout 记为 宏3。内部的 resolved 微任务记为 微1。在 微1 内部又有一个 setTimeout 记为 宏4。最后一个 setTimeout 记为 宏5
执行 宏2,执行代码 console.log("1") 打印 1。
执行 宏3,执行代码 console.log("2") 打印 2。
执行 宏3 中的 微1,执行代码 console.log("3") 打印 3。
执行 宏5,执行代码 console.log("5") 打印 5。
执行 宏4,执行代码 console.log("4") 打印 4。

结果:1 2 3 5 4

题目5:

如果微任务中有微任务…

<script>
    setTimeout(()=> {
        console.log("1")
    })
    var pro = new Promise((resolved,rejected)=>{
        resolved("3")
    });
    pro.then((res)=>{
        Promise.resolve().then(()=>{
            console.log("4")
        });
         setTimeout(()=> {
           console.log("2")
        })
        console.log(res)
    })
</script>

解析:
第一个 setTimeout 记为 宏2,接下来在 Promise 中 resolved 记为 微1微1 中的微任务记为 微2微1 中的宏任务记为 宏3
执行 微1,执行代码 console.log(res) 打印 3。
执行 微2,执行代码 console.log("4") 打印 4。
执行 宏2,执行代码 console.log("1") 打印 1。
执行 宏3,执行代码 console.log("2") 打印 2。

结果:3 4 1 2。

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值