⚡ 30 秒速记

  • 核心判断:JavaScript 单线程描述的是执行代码的主线程,异步能力来自宿主环境、任务队列与事件循环协作
  • 原理主线:围绕 「同步任务与异步任务」、「同步任务与函数调用栈」、「异步任务与回调队列」 建立输入、状态变化与输出之间的因果关系
  • 文章范围:解析了 JavaScript 单线程模型,介绍了同步任务与异步任务的区别、函数调用栈的工作原理,以及浏览器如何高效管理和执行各类任务,帮助读者理解 JavaScript 任务调度机制和性能优化思路。
  • 边界与代价:浏览器与 Node.js 的阶段、微任务清空时机并不完全相同,长任务仍会阻塞渲染和输入
  • 工程落地:排障时同时观察调用栈、微任务、宏任务和渲染机会,不能只背固定输出顺序

JavaScript 的单线程指主线程一次只执行一个任务,异步能力则由宿主环境、任务队列和事件循环配合提供。 同步代码进入调用栈顺序执行,定时器、网络请求或用户事件完成后,其回调才会进入相应队列,等调用栈清空后再被取出。每个宏任务结束后会清空微任务队列,浏览器还可能在下一个宏任务前更新界面。长任务仍会阻塞交互,计时器也可能因队列拥堵而延迟;Node.js 的阶段划分及 Node.js 11 前后的微任务处理差异也要结合版本判断。

这篇文章不要按 API 清单来背。先用上面的 Mind Map 建立全局结构,再通过交互 DEMO 观察正常路径和边界路径如何改变状态;阅读正文时重点核对每一步的输入、负责执行的参与者、产生的中间状态以及最终可观察结果。遇到版本敏感结论,要把“历史实现”“当前行为”和“工程兼容策略”分开说明;遇到性能或架构取舍,则用实际指标、失败现象和验证手段支撑判断。

版本校准: 原理文章中的代码代表特定实现与写作时间。应用到当前项目时,应先确认浏览器、框架或工具的主版本,再区分稳定的规范语义、可变化的内部实现和项目自身约束。

要怎么理解 JavaScript 是单线程这个概念呢?大概需要从浏览器来说起。

JavaScript 最初被设计为浏览器脚本语言,主要用途包括对页面的操作、与浏览器的交互、与用户的交互、页面逻辑处理等。如果将 JavaScript 设计为多线程,那当多个线程同时对同一个 DOM 节点进行操作时,线程间的同步问题会变得很复杂。

因此,为了避免复杂性,JavaScript 被设计为单线程。

这样一个单线程的 JavaScript,意味着任务需要一个接一个地处理。如果有一个任务是等待用户输入,那在用户进行操作前,所有其他任务都处于等待状态,页面会进入假死状态,用户体验会很糟糕。

那么,为了高效进行页面的交互和渲染处理,我们围绕着任务执行是否阻塞 JavaScript 主线程,将 JavaScript 中的任务分为同步任务和异步任务

# 同步任务与异步任务

  • 同步任务:在主线程上排队执行的任务,前一个任务完整地执行完成后,后一个任务才会被执行
  • 异步任务:不会阻塞主线程,在其任务执行完成之后,会再根据一定的规则去执行相关的回调。
webapp
公众号
开发者导航
切换夜间模式
点击侧边栏上一篇
点击侧边栏下一篇
折叠侧边栏
收起全部