欢迎光临
我们一直在努力

前端八股整理(代码输出 02)|宏任务微任务 promise await 代码输出题

前端八股整理(代码输出 02)|宏任务微任务 promise await 代码输出题

本文速览

一句话总结:
本文主要讲清楚 JavaScript 事件循环、宏任务、微任务、Promise 和 async/await 的执行顺序,帮助你理解代码输出题的核心判断逻辑,并能解决前端面试中常见的异步执行顺序题目。

适合人群:
适合正在准备前端面试、学习 JavaScript 异步机制、容易在 Promise / async / await 输出题中出错的同学阅读。

核心问题:

  • 宏任务和微任务的执行顺序是什么?

  • Promise 的 executor 和 then 分别什么时候执行?

  • setTimeout、Promise、async/await 混在一起时应该怎么判断输出顺序?

  • 面试中的异步代码输出题有哪些常见考点?

  • 你将学会:

    • 理解事件循环中宏任务和微任务的基本执行流程

    • 掌握 Promise executor 同步执行、then 回调进入微任务队列的规则

    • 理解 Promise 状态一旦改变就不可逆

    • 理解 async / await 和 Promise.then 之间的关系

    • 能够独立分析常见的 JavaScript 异步代码输出题

    相关关键词:
    JavaScript、事件循环、宏任务、微任务、Promise、async/await、setTimeout、代码输出题、前端面试

    1.事件循环基础

    1.1 宏任务与微任务执行顺序

    执行顺序如下:

    • 执行一次宏任务(最开始会是整个srcipt所以上面的例子会先执行console.log(1))
    • 执行过程中如果遇到宏任务,就放进宏任务列队
    • 执行过程中如果遇到微任务,就放进微任务列队
    • 当执行栈空了,先检查微任务列队,如果有微任务,就依序执行直到微任务列队为空
    • 接着进行浏览器的渲染,渲然完后开始下一个宏任务(回到最开始的步骤)

    1.2 Promise 执行机制

    • promise中的执行器函数(executor)是同步执行的,也就是直接加入到执行栈中执行
    • resolve 触发后,才将对应的.then 的部分加入微任务队列
    • 如果既存在 resolve,又存在 reject,那么只会执行他们之中的第一个,因为Promise 状态一旦从 pending 变成 fulfilled,就不可能变成 fulfailed

    1.3 setTimeout 执行机制

    • setTimeout 加入宏任务队列中

    1.4 async / await 执行机制

    • await async2() 会同步立即执行 async2,并且把 await 后面的代码包装成一个「微任务」去执行

    async/await 可以理解成 Promise.then() 的语法糖

    await 后面跟一个普通函数的时候,会先正常执行,拿到返回值后,再用 Promise.resolve 包一层,然后后面的代码进行到微任务队列中继续执行

    2.实战题目

    2.1 模拟实战

    给出下面代码的输出:

    console.log('A');

    const p = new Promise((resolve, reject) => {
    // 这段就是 executor(执行器函数)
    console.log('B: executor start');

    resolve('OK');

    console.log('C: executor end');
    });

    p.then((value) => {
    console.log('E: then', value);
    });

    console.log('D');

    A
    B: executor start
    C: executor end
    D
    E: then

    console.log(1);

    setTimeout(function () {
    console.log(2);
    }, 0);

    Promise.resolve()
    .then(function () {
    console.log(3);
    })
    .then(function () {
    console.log(4);
    });

    1
    3
    4
    2

    console.log("begins");

    setTimeout(() => {
    console.log("setTimeout 1");
    Promise.resolve().then(() => {
    console.log("promise 1");
    });
    }, 0);

    new Promise(function (resolve, reject) {
    console.log("promise 2");
    setTimeout(function () {
    console.log("setTimeout 2");
    resolve("resolve 1");
    }, 0);
    }).then((res) => {
    console.log("dot then 1");
    setTimeout(() => {
    console.log(res);
    }, 0);
    });

    begins
    promise 2
    setTimeout 1
    promise 1
    setTimeout 2
    dot then 1
    resolve 1

    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");

    script start
    async1 start
    async2
    promise1
    script end
    async1 end
    promise2
    setTimeout

    2.2 真题实战

    来源:腾讯音乐 暑期二面

    new Promise((resolve, reject) => {
    console.log("p1");
    resolve();
    console.log("p2")
    reject();
    }).then(() => {
    console.log("then1");
    new Promise((resolve, reject) => {
    console.log("p2");
    resolve();
    }).then(() => {
    console.log("then2");
    }).then(() => {
    console.log("then3");
    });
    }, () => {
    console.log("then4")
    })

    p1
    p2
    then1
    p2
    then2
    then3

    赞(0)
    未经允许不得转载:171主机测评 » 前端八股整理(代码输出 02)|宏任务微任务 promise await 代码输出题
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址