面试题 - 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。

发布了280 篇原创文章 · 获赞 2497 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/weixin_44135121/article/details/104784949