上一篇文章【JavaScript 入門:什麼是一等函式、高階函式 (HOF) 與回呼函式 (Callback)】中,介紹了高階函式與回呼函式。上一篇的範例,回呼函式都是被立刻執行,今天要介紹的就是「不會立刻執行的函式」也就是非同步函式 Asynchronous function。
同步與非同步
同步 Synchronous
同步的意思是:一件事做完才會做下一件事。例如:
console.log("A");這段程式碼的執行順序會是:
console.log("B");
console.log("C");
A
B
C
非同步 Asynchronous
非同步的意思就與同步相反:某些事情可以先交代出去,之後再回頭處理。例如:
console.log("A");
setTimeout(()=>{
console.log("B");
},1000)
console.log("C");
這段程式的結果會是:
A
C
B
為什麼明明 setTimeout 寫在中間,卻在最後才印出 "B"?
我們來仔細看一下,setTimeout 接收了一個箭頭函式,並且在 1000 毫秒後執行被傳入的函式。setTimeout 就是上一篇介紹的「高階函式」,而被傳入等待執行的箭頭函式就是「回呼函式」。
如果忘記高階函式的概念可以回來看這篇文章:【JavaScript 入門:什麼是一等函式、高階函式 (HOF) 與回呼函式 (Callback)】
在這個非同步函式的例子中,JS 並不會在原地等待一秒、執行完 console.log("B") 後再接著往下執行 console.log("C"),而是把「等待一秒」這個工作交給瀏覽器的計時機制處理,主程式先去執行 console.log("C"),等一秒過後才回頭執行 console.log("B")。
所以說,
非同步函式就是:不會阻塞主程式運行,而是將需要等待的工作交出去,等結果準備好後再繼續處理的函式。
為何需要非同步函式
JavaScript 最初是設計跑在瀏覽器上的,如果每次執行下一個動作都要等前面的動作完成,可能會造成網頁不順暢。
舉例來說,如果沒有非同步,JS 在等待資料從資料庫或伺服器取撈回來的這段時間畫面會不能點擊、不能滾動,除了看起來像是當機外,使用體驗也會很差。因此 JS 利用非同步的設計,把需要等待的工作交出去,主程式可以繼續跑,等取得結果後再回頭處理。
非同步函式的目的是要避免耗時的任務(像是網路請求或定時器)阻塞執行緒,確保網頁在等待結果時仍能順暢地回應使用者的操作。
結論
同步與非同步的差異在於程式是否會「等待前一件事完成」才繼續往下執行。
同步函式會依序完成程式碼,而非同步函式則會將需要等待的工作交出去,讓主程式可以先往下執行其他任務,等待結果完成後再回頭處理回呼函式。這樣的設計讓 JavaScript 即使在等待耗時任務的同時也可以保持畫面流暢與良好的使用者體驗。
下一篇文章,我們會進一步介紹 JavaScript 中的非同步函式怎麼實現,從 callback、promise 到 async/await 的概念逐步了解這些方法如何解決非同步函式的問題。














