文章
2026年7月9日 - 6 MIN READ
Async 到底在解決什麼問題?

Async 到底在解決什麼問題?

從「等待」的角度重新理解非同步存在的目的,並拆解 I/O、計時器、使用者互動、執行緒同步、硬體協作等不同類型的等待。

Gary

Gary

核心結論

Async 存在的唯一目的,就是解決**「等待」**這件事——讓 CPU(或執行緒)在等待外部資源回應的空檔,不要傻傻卡住浪費掉,而是先去做別的事,等結果準備好了再回來處理。


為什麼「等待」值得特別解決

CPU 執行一個指令的時間,如果放大成 1 秒,等網路回應可能相當於等 3~9 年。這麼懸殊的速度差,如果同步等待,CPU 幾乎全部時間都在「浪費」——這才是 async 機制被發明出來的根本原因。


反面驗證:沒有等待的地方,async 就沒意義

  • CPU 密集型任務:全程都在運算,沒有空檔可以利用,async 幫不上忙,需要靠平行運算而不是 async
  • RAM 存取:延遲只有幾十奈秒,是 CPU 指令的內建流程,時間短到連排程切換的成本都划不來,不需要、也沒辦法做 async 處理

I/O 密集與 CPU 密集的速度數字、分界線與執行緒數怎麼開,可參考 I/O 密集 vs CPU 密集:執行緒數該開多少? 一文。


完整因果鏈

外部資源比 CPU 慢很多(I/O)
      ↓
如果同步等待 → CPU 大量時間閒置浪費
      ↓
用 async(非阻塞 I/O + 事件通知)
      ↓
CPU 不用傻等,先做別的事,等通知了才回來處理
      ↓
單一執行緒也能高效應付大量並發的「等待中」任務

這條邏輯串起了為什麼需要 callback/Promise(拿到「以後通知我」的入口)、為什麼 epoll 能用一條執行緒處理上萬連線(不用傻等)、為什麼 CPU 密集任務用不上 async(沒有等待可以省)——全部都是圍繞著「解決等待浪費」這個核心目的展開的。


「等待」不等於「I/O」

I/O 只是「等待」裡最大宗、最常被討論的一種,但不是唯一的一種。

1. I/O 等待

等待外部裝置回應:網路、硬碟、鍵盤滑鼠等,需透過 OS 的 I/O 子系統(driver、匯流排)。

fetch('/api/data')       // 等網路
fs.readFile('a.txt', cb) // 等硬碟

2. 計時器等待

嚴格說不算 I/O,但用同一套機制處理。

setTimeout(() => {}, 1000) // 純粹等時間過去,沒有資料進出任何裝置

這裡沒有任何資料在「進出」,單純是等時鐘走到某個時間點。技術上不算 I/O,但底層處理方式跟 I/O 一模一樣:靠硬體計時器 + 事件通知,不需要 CPU 傻等,時間到了才觸發 callback。

3. 使用者互動等待

廣義算 I/O,但性質特殊。

button.addEventListener('click', () => {})

鍵盤滑鼠技術上是輸入裝置,勉強可以歸類到 I/O,但特殊之處在於:等待時間完全不可預測,甚至可能永遠不會發生(使用者可能永遠不點擊)。這跟「等網路封包,通常幾百毫秒內會有結果」的性質不太一樣。

4. 執行緒/行程間的同步等待

跟 I/O 無關。

// 等另一條 Worker thread 算完
worker.postMessage('start')
worker.onmessage = (e) => {}

// 等多個非同步任務都完成
await Promise.all([task1(), task2()])

等待的對象是別的執行緒/行程,不是外部裝置——是在等「別人算完」或「別人放開資源」,但一樣需要非阻塞機制去處理,不然當前執行緒一樣會卡住浪費。

5. 硬體加速器等待

也不算傳統 I/O。

// WebGPU 等 GPU 運算完成
await device.queue.onSubmittedWorkDone()

等 GPU 算完一段運算,這不是資料進出裝置,而是等另一個運算單元完成工作,性質上更接近「同步等待」而非「I/O 等待」。


分類總表

等待類型等待對象算不算 I/O?
網路/硬碟請求外部裝置✅ 是
計時器(setTimeout時間本身❌ 不算,機制類似
使用者互動⚠️ 廣義算(輸入裝置),性質特殊(不可預測)
Worker / Promise.all其他執行緒/非同步任務❌ 不算,是同步協調問題
GPU 運算另一個運算單元❌ 不算,是協作等待

結論

Async 要解決的核心問題,不是狹義的「I/O」,而是更廣義的:等待某個結果,而這個結果何時準備好,不由自己這條執行緒的程式碼控制。I/O 是這個大類別裡最常見、最具代表性的例子(因為速度差距最誇張),但計時器、使用者互動、執行緒同步、硬體協作,本質上都是同一種「等待」問題,只是等待的對象不同。

非同步的三個演進階段與適用場景,可參考 同步 vs 非同步 一文。

Callback 的完整定義與判斷標準,可參考 Callback 是什麼? 一文。

Gary Portfolio • © 2026