JavaScript 宏任务与微任务执行机制详解

作者:小括号时间:2026-10-24 12:37:48浏览:356

本文详细解析JavaScript单线程模型下的事件循环机制,重点阐述宏任务与微任务的定义、执行顺序及相互关系。通过定时器模块与Promise的具体案例,说明同步代码、微任务队列与宏任务队列的调度逻辑,帮助开发者掌握异步编程的核心原理。

宏任务与微任务

  • JavaScript采用单线程运行机制,这是为了避免多线程操作DOM时可能引发的复杂状态冲突。
  • 因此,在任意给定时刻,主线程仅负责执行一个任务,主要用于处理同步代码。
  • 与此同时,系统维护着两个独立的任务队列,分别用于存放宏任务和微任务,以处理异步操作。
  • 整体的执行优先级顺序为:主线程执行同步任务,随后清空微任务队列,最后处理宏任务。

关于定时器模块

  1. 定时器模块在到达指定时间点时,会将回调函数放入宏任务队列中等待执行。
  2. 若主线程当前无其他任务,则立即执行该宏任务;若主线程繁忙,则需等待当前同步任务执行完毕后,再按顺序执行宏任务。
  3. 当存在多个触发时间相同的定时器时,按照注册顺序,先注册的先执行,后注册的后执行。
  4. 若多个定时器的触发时间不同,则耗时较短的定时器回调会先于耗时较长的回调被执行。

需要注意的关键点:

  • 定时器的计时过程在定时器模块内部完成,一旦计时结束,其回调行为便与普通异步任务无异。
  • 由于主线程可能长时间被同步任务占用,定时器的实际执行时间可能会发生延迟。


宏任务与微任务

关于Promise对象

  • Promise构造函数的执行属于同步任务,会立即运行。
  • 无论代码结构如何嵌套,最终执行顺序始终遵循:同步代码 -> 微任务 -> 宏任务。
  • 在嵌套代码场景中,若宏任务内部包含同步代码、宏任务或微任务,这些子任务会被推入相应的队列,并在当前宏任务结束后,于下一轮事件循环中依次执行。

setTimeout(() => {
    console.log("定时器");
    setTimeout(() => {
      console.log("timeout timeout");
    }, 0);
    new Promise(resolve => {
      console.log("settimeout Promise");
      resolve();
    }).then(() => {
      console.log("settimeout then");
    });
  }, 0);
  new Promise(resolve => {
    console.log("Promise");
    resolve();
  }).then(() => {
    console.log("then");
  });
  console.log("ssss");

具体的执行输出顺序为:Promise -> ssss -> then -> 定时器 -> setTimeout Promise -> setTimeout then -> timeout timeout。

DOM渲染任务

浏览器在渲染页面时,处理CSS和DOM结构若遇到JavaScript代码,会优先执行JS。为避免白屏现象,建议将JS脚本尽量放置在HTML底部。

任务共享内存

由于任务是串行执行的,它们依次被调度器处理,但所有任务共享同一块内存空间。

Promise微任务处理复杂业务

利用Promise可以将复杂业务逻辑转化为异步任务,从而避免阻塞同步任务的执行。

至此,关于JavaScript宏任务与微任务的介绍已结束,更多相关内容请参阅本站过往文章或继续浏览后续章节。

作者最新文章