• 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
  • 相关阅读:
    【重识云原生】第六章容器基础6.4.9.6节——Service 与 Pod 的DNS
    MaterialDesign组件
    Angular: 变化检测策略Change Detection的比较
    linux中正则匹配
    暴力美学,拒绝平庸,Alibab开源内部神仙级“K8S核心笔记”下载
    黑盒测试-场景法
    视频解锁【物联网技术在物联网产业格局的分布与应用】
    Android Live Edit 给 Android开发者带来的福音
    【环境配置】Windows10上的OpenFace安装与使用
    左连接一对多的情况
  • 原文地址:https://blog.csdn.net/m0_71485750/article/details/125521479