Javascript 宏任务和微任务详解

前言我们知道,JavaScript 是一种单线程的编程语言,意味着它一次只能执行一个任务。这就会导致后面的任务需要等到前面的任务完成才能执行,如果前面的任务很耗时就会造成后面的任务一直等待,形成阻塞。

为了解决这个问题,JS引入了同步任务和异步任务,来解决等待的问题。为了管理任务的执行顺序,又引入了宏任务(MacroTask)和微任务(MicroTask)的概念,宏任务和微任务都属于异步任务。代码执行过程中,碰到宏任务会放入宏队列,碰到微任务放入微队列。

同步任务:在主线程上排队执行的任务只有前一个任务执行完毕,才能执行后一个任务,形成一个执行栈。

异步任务:不进入主线程,而是进入任务队列,当主线程中的任务执行完毕,就从任务队列中取出任务放进主线程中来进行执行。

事件循环:主线程执行过程中不断重复的获取任务、执行任务,再获取再执行,这种机制就被叫做事件循环(Event Loop)。

JavaScript 的事件循环(Event Loop)机制是理解异步编程的关键。在这个机制中,"宏任务"(MacroTask)和"微任务"(MicroTask)是两个核心概念。

一、分类:

类型示例执行顺序
同步代码console.log()、变量赋值、循环等最先执行,不会被放入任何队列
微任务PromisequeueMicrotask(手动添加的微任务)、MutationObserver(监听DOM变化)当前宏任务执行完后,立即执行所有积累的微任务
宏任务setTimeoutsetInterval、

Dom事件如点击、滚动、requestAnimationFrame、UI渲染、整个脚本的执行(首次执行)等

一次事件循环中所有微任务执行完后,从宏任务队列中选取下一个任务执行,即每次事件循环执行一个

二、执行流程: 

  1. 执行当前宏任务:例如,开始执行一个脚本文件。

  2. 执行所有微任务:在执行完当前宏任务后,立即执行所有积累的微任务。

  3. 渲染更新:如果需要,浏览器会进行一次 UI 渲染。

  4. 选择下一个宏任务:从宏任务队列中选取下一个任务执行。

简单来说,同步代码是 JavaScript 的主线程任务,而宏任务和微任务是异步任务,一次事件循环中,它们的执行顺序是:同步代码 → 微任务 → 宏任务

三、举个简单栗子

console.log("同步代码 1");

// 宏任务
setTimeout(() => {
  console.log("setTimeout 回调");
}, 0);

// 微任务
Promise.resolve().then(() => {
  console.log("Promise 回调");
});

console.log("同步代码 2");

可以看下上面代码的打印顺序为:同步代码 1、同步代码 2、Promise 回调、setTimeout 回调

做下简单分析:
1. 代码首次执行时,即进入了当前宏任务,首先碰到 console,属于同步代码,直接打印;(打印 同步代码 1)
2. 继续往下碰到 setTimeout,属于宏任务,放入宏队列;(放入 宏队列等待)
3. 继续往下碰到 Promise,属于微任务,放入微队列;(放入 微队列等待)
4. 再往下又碰到 console,同步代码直接打印;(打印 同步代码 2)
5. 同步代码执行完后,检查微队列,发现 Promise,执行;(打印 Promise 回调)
6. 微队列所有任务执行完成,检查宏队列,发现 setTimeout,执行,进入下一个宏任务。(打印 setTimeout 回调)

四、来个复杂点的栗子

const fn1 = async () => {
    console.log(1);
    await fn2();
    console.log(2);
};

const fn2 = async () => {
    await setTimeout(() => {
        Promise.resolve().then(() => {
            console.log(3);
        });
        console.log(4);
    }, 0);
};

const fn3 = async () => {
    Promise.resolve().then(() => {
        console.log(6);
    });
};

fn1();
console.log(7);
fn3();



有知道的小伙伴可以打在评论区哦~(答案后续公布)

五、总结

  • 宏任务:适合处理需要延迟执行或者周期性的任务,如定时器、用户交互事件等。

  • 微任务:适合处理需要尽快完成的回调,如异步操作的结果处理、DOM 更新后的操作等。

  • 过多的微任务可能会导致页面响应变慢,因为它们会在每个宏任务之后立即执行,可能会阻塞 UI 渲染。

  • 合理安排宏任务和微任务的使用,可以提高应用的性能和用户体验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值