• JavaScript中Promise、事件循环、宏任务微任务综合面试题详解


    Promise、事件循环试题一

    写出下面代码的执行顺序:

    setTimeout(function () {
      console.log("setTimeout1");
      new Promise(function (resolve) {
        resolve();
      }).then(function () {
        new Promise(function (resolve) {
          resolve();
        }).then(function () {
          console.log("then4");
        });
        console.log("then2");
      });
    });
    
    new Promise(function (resolve) {
      console.log("promise1");
      resolve();
    }).then(function () {
      console.log("then1");
    });
    
    setTimeout(function () {
      console.log("setTimeout2");
    });
    
    console.log(2);
    
    queueMicrotask(() => {
      console.log("queueMicrotask1")
    });
    
    new Promise(function (resolve) {
      resolve();
    }).then(function () {
      console.log("then3");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    分析:

    1. 初次执行会打印下面的全局代码
    // 全局代码打印
    // promise1
    // 2
    
    • 1
    • 2
    • 3
    • 并将对应的异步放入对应的宏任务队列和微任务队列
    // 宏任务队列的函数
    // 1.第一个函数
    setTimeout(function () {
      console.log("setTimeout1");
      new Promise(function (resolve) {
        resolve();
      }).then(function () {
        new Promise(function (resolve) {
          resolve();
        }).then(function () {
          console.log("then4");
        });
        console.log("then2");
      });
    });
    // 2.第二个函数
    setTimeout(function () {
      console.log("setTimeout2");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    // 微任务队列的函数
    // 1.第一个函数 下面这个Promise中的then方法的回调
    new Promise(function (resolve) {
      console.log("promise1");
      resolve();
    }).then(function () {
      console.log("then1");
    });
    
    // 2.queueMicrotask函数
    queueMicrotask(() => {
      console.log("queueMicrotask1")
    });
    
    // 3.第三个函数 下面这个Promise中的then方法的回调
    new Promise(function (resolve) {
      resolve();
    }).then(function () {
      console.log("then3");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 全局代码执行完后, 会按照顺序执行微任务队列
    // 全局代码打印
    // promise1
    // 2
    
    // 微任务队列第一次打印
    // then1
    // queueMicrotask1
    // then3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 当微任务队列中全部执行完成时, 就会按照顺序执行宏任务队列
    // 全局代码打印
    // promise1
    // 2
    
    // 微任务队列第一次打印
    // then1
    // queueMicrotask1
    // then3
    
    // 宏任务队列第一次打印
    // setTimeout1
    // then2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 当执行到宏任务队列的第一个函数, 发现有Promise的then方法, 又会将then方法的回调放入, 此时宏任务和微任务中函数分别如下
    // 宏任务队列的函数
    
    // 1.第一个函数
    setTimeout(function () {
      console.log("setTimeout2");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    // 微任务队列的函数
    
    // 1.第一个函数
    function () {
    	new Promise(function (resolve) {
    	resolve();
    }
    
    // 2.第二个函数
    function () {
    	console.log("then4");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 当执行完宏任务队列中第一个函数, 会发现微队列中又添加了新的成员, 便会暂停执行宏任务队列, 继续执行微任务队列
    // 全局代码打印
    // promise1
    // 2
    
    // 微任务队列第一次打印
    // then1
    // queueMicrotask1
    // then3
    
    // 宏任务队列第一次打印
    // setTimeout1
    // then2
    
    // 微任务队列第二次打印
    // then4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 微任务队列再次为空之后, 再执行宏任务队列就是最终打印顺序
    // 全局代码打印
    // promise1
    // 2
    
    // 微任务队列第一次打印
    // then1
    // queueMicrotask1
    // then3
    
    // 宏任务队列第一次打印
    // setTimeout1
    // then2
    
    // 微任务队列第二次打印
    // then4
    
    // 宏任务队列第二次打印
    // setTimeout2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Promise、事件循环试题二

    同样写出下面代码的打印顺序, 思路和上面一样

    async function async1 () {
      console.log('async1 start')
      await async2();
      console.log('async1 end')
    }
    
    async function async2 () {
      console.log('async2')
    }
    
    console.log('script start')
    
    setTimeout(function () {
      console.log('setTimeout')
    }, 0)
     
    async1();
     
    new Promise (function (resolve) {
      console.log('promise1')
      resolve();
    }).then (function () {
      console.log('promise2')
    })
    
    console.log('script end')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    这里直接给出答案

    // script start
    // async1 start
    // async2
    // promise1
    // script end
    // async1 end
    // promise2
    // setTimeout
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    小白备战大厂算法笔试(八)——搜索
    【leetcode】【剑指offer Ⅱ】028. 展平多级双向链表
    深入理解Spring、Spring MVC、Spring Boot等开源框架
    如何借用敏捷实现IT对数字化转型支持 | 2023佛山敏捷之旅成功举办
    app自动识别ios或安卓手机,微信浏览器,并下载相应的apk安装包
    [SLAM] 传感器总结
    Shell脚本相互调用并指定返回值
    零样本文本分类应用:基于UTC的医疗意图多分类,打通数据标注-模型训练-模型调优-预测部署全流程。
    JavaScript变量、数据类型、类型转换
    VUE扫码枪中文输入法兼容自动回车事件
  • 原文地址:https://blog.csdn.net/m0_71485750/article/details/125521479