為什么 JavaScript 到 2025 年還是單線程?
沒錯——手機 12 核、冰箱跑 Linux 的今天,JavaScript 依舊像 1995 年那樣一件事接一件事地做。 最離譜的是?它還挺好用。
可這是怎么做到的?
JavaScript 是“10 天速成”的(真的)
1995 年,Brendan Eich 用十天造出了 JavaScript——比你刷完一部劇的時間還短。
它的最初使命只有一個:
“讓網頁稍微有點交互。點個按鈕?彈個 alert。就這樣?!?/span>
為了簡單且安全,它被設計為單線程:
- 沒有線程
- 沒有鎖
- 沒有死鎖
- 沒有讓人抓狂的競態
一次只干一活、一個全局線程、一條巨大的待辦隊列。 這套哲學,直到今天也沒根本改變。
“單線程”到底指什么?
JavaScript 只有一個調用棧:同一時刻只執行一段代碼,A 沒跑完,B 不會上來。 看一段小例子:
console.log("One");
setTimeout(() => console.log("Two"), 1000);
console.log("Three");輸出順序是:
One
Three
Two原因很簡單:setTimeout不阻塞主線程。它的意思大概是:
“嗨瀏覽器,一秒后幫我回調一下行嗎?”
主線程點點頭,繼續往下跑。
撐起這一切的,是傳說中的——事件循環(Event Loop)。
事件循環:JS 的“魔法醬汁”
把它想象成這樣:
- 調用棧(Call Stack):函數在這兒真正執行;
- 任務隊列(Task/Callback Queue):回調、事件在這兒排隊等候;
- 事件循環(Event Loop):像門口保安一樣重復檢查—— “??樟藛幔靠樟司?/span>請下一位?!?/span>
需要強調的是:JS 本體是單線程,但瀏覽器/Node.js會在幕后多線程地代勞:
- 網絡請求 → 在后臺線程處理;
- 文件讀寫 → 背景完成再回調;
- 定時器、DOM 事件、數據庫訪問 → 先異步完成,后入隊等待主線程空閑。
JS 自己不并發——它會把活外包。
“都 2025 了,為啥不把 JS 直接做成多線程?”
聽上去理所當然,對吧?CPU 有 32 線程,JS 也該上吧。然而,真相是:
整個 Web 的設計默認 JavaScript 是單線程。 DOM、CSSOM、事件系統、各種瀏覽器 API——都假設同一時刻只有一個“家伙”在動它們。 如果 JS 突然能多線程同時改 DOM,你最愛的站點會像熱鍋上的黃油一樣糊成一攤。
但還有個東西叫 Web Workers,不是嗎?
沒錯,它們很香。Web Workers 允許你開真正的后臺線程并行跑 JS??梢灿写鷥r:
- ?? 不能操作 DOM;
- ?? 通過
postMessage()通訊; - ?? 數據需要序列化/反序列化。
因此它們適合:
- 重計算(數值、圖像、視頻處理);
- AI 推理(比如 TensorFlow.js);
但你若在 Worker 里想 document.querySelector('div') 并改它?不行。DOM 歸主線程管。
服務器端的“多線程”:Node.js 的 Worker Threads
Node 也曾以單線程聞名。如今(Node 12+ 起),Worker Threads 讓它更能打:
- 為 CPU 密集任務開多個工作線程;
- 用 SharedArrayBuffer 進行內存共享;
- 依舊 事件驅動,但更強壯。
2025 年,高性能 Node 應用通常把 異步 I/O 和 Workers 搭著用,既靈活又狠快。
async/await:把“隊列戲法”偽裝成“多線程”
JS 史上最出神入化的把戲,也許就是這對黃金搭檔。async/await 看起來像同步:
async function fetchData() {
const res = await fetch("https://api.whatever.com");
const data = await res.json();
console.log(data);
}它像同步、行徑卻是異步——背后靠 Promise + 事件循環 調度。沒線程參與。純粹的錯覺,Copperfield 都會點個贊。
框架陣營如何應對?(React / Vue 等)
即便是現代框架,也默認遵守單線程模型。
這就是為什么 React 18 引入了并發特性(Concurrent Features):通過調度讓渲染更聰明,而不是去開十個線程。
React 的渲染可以暫停 / 推遲 / 取消,以避免卡住主線程、提升交互流暢度。線程只有一個,體驗卻能更絲滑。
單線程 = 更安全的默認
樸素的模型,帶來可貴的“無聊”:
- 無共享內存引發的詭異 Bug;
- 無死鎖;
- 無互斥鎖地獄;
- 更低的心智負擔。
Web 的基石要的是可預期。你可不希望網銀因為兩個線程“搶一個 div”而抽風。
接下來會怎樣?JS 會邁向“多線程常態”嗎?
也許吧,但不會很快。 相關方向已經有:
- Atomics / SharedArrayBuffer(更底層的并發原語);
- WebAssembly with Threads(WASM 線程化);
- 更靈活的 Workers / 調度模型。
盡管如此,離“隨手就多線程的 JS”仍有不短的距離。 可能這也沒什么不妥——這門“30 歲的單線程語言”,仍然扛著幾乎整個 Web,而且不打算退場。
JavaScript 并不“笨”——它是“老而聰明”
下回有人吐槽“單線程太拉了”,你可以這樣回他:
“不,它只是把并發隱藏在舞臺后??渴录h與一堆 Workers,它把混亂編排得井井有條。 它只是不允許你從十個線程同時戳 DOM,然后還自稱聰明?!?/span>
這就是 JavaScript 的美學:單線程,卻從不無聊。




























