JavaScript 同步與非同步

JavaScript 同步與非同步
Katechou一、JavaScript 在做事情時的規則(超重要)
JavaScript 是「一次只能做一件事」的語言
你可以把 JavaScript 想成:
👦 一個只有「一個腦袋、一雙手」的小朋友
這個小朋友:
- 一次只能做一件事情
- 做完一件,才會做下一件
這就叫做:
👉 單執行緒(Single Thread)
什麼是「同步」?
同步 = 排隊一個一個來
就像你在洗手:
- 先開水龍頭
- 洗手
- 關水龍頭
前一步沒做完,後一步不能開始
同步的特點
- 程式會照順序跑
- 前一行沒跑完,下一行一定不會跑
- 如果卡住了,後面全部都停住
什麼是「非同步」?
非同步 = 先交代,之後再回來
就像你請媽媽幫你煮泡麵:
- 你跟媽媽說:「幫我煮泡麵」
- 媽媽去煮
- 你先去寫作業
- 泡麵好了,媽媽再叫你
👉 你不用站在旁邊等
JavaScript 什麼時候會用非同步?
常見情況:
- 跟網路要資料(API、AJAX)
- 倒數計時(
setTimeout)
因為這些事情:
- 需要時間
- JavaScript 不想傻傻等
二、同步「卡住」的例子
範例一:alert 為什麼很討厭?
1 | console.log('開始執行'); |
發生什麼事?
- 顯示「開始執行」
- 跳出 alert 視窗
- 一定要你按「確定」
- 才會顯示「結束執行」
為什麼不推薦?
因為:
- 整個網頁都被卡住
- 使用者什麼都不能做
👉 實務上幾乎不會用 alert
範例二:for 迴圈為什麼會卡?
1 | console.log(1); |
為什麼一定先跑完 for?
因為 JavaScript 會說:
「我一定要把這個 for 全部跑完,
才能去做下一件事」
所以:
2一定最後才出現
同步一句話總結
同步就是:一件事情沒做完,後面的事情全部不能開始
三、setTimeout 在做什麼?
很重要的一件事
❗
setTimeout不是 JavaScript 本身的能力
JavaScript 其實:
- 不會計時
- 不會自己等秒數
所以它會:
👉 把事情「交給外面的人幫忙」
這個「外面的人」叫做 Web APIs
範例來看順序
1 | console.log(1); |
實際輸出
1 | 1 |
為什麼不是 1 2 3 4?
發生流程像這樣:
- JavaScript 先把「同步的事情」做完
👉 印出 1、3、4 setTimeout交給 Web APIs- 等全部事情都空了
- 才回來印 2
👉 不是 0 秒就馬上跑
一句話記住
所有非同步的事情,一定最後才執行
四、為什麼串 API 會出問題?
想像你跟後端要資料:
- 有時很快
- 有時很慢
- 有時網路卡住
👉 你不能保證什麼時候拿到
❌ 錯誤寫法
1 | const data = fetch('/api/users'); |
為什麼錯?
因為:
fetch是「去要資料」- 資料還沒回來
- 你就急著印
所以你只會看到:
👉 Promise(等待中)
五、Promise 是什麼?
Promise 就像一張:
📄「我保證之後會給你答案」的紙
但現在:
- 還不知道結果
- 只能等
Promise 三種狀態(很重要)
- ⏳ 等待中(Pending)
- ✅ 成功(Fulfilled)
- ❌ 失敗(Rejected)
Promise 範例(用白話想)
1 | const promise = new Promise((resolve, reject) => { |
意思是:
「2 秒後,我會告訴你結果」
六、async / await 是什麼?
超簡單說法
讓你用「看起來像同步」的方式,寫非同步程式
範例
1 | async function fetchData() { |
await 在幹嘛?
意思是:
「這一行我先等一下,
等結果回來再繼續」
但注意:
- JavaScript 不是真的卡住
- 它只是「先去做別的事」
為什麼大家愛用?
因為:
- 好讀
- 好寫
- 好維護
- 不用
.then()一直接
七、為什麼會看到 Promise <pending>?
1 | const data = promiseSetTimeout(1); |
原因超簡單
因為你在說:
「我現在就要答案」
但實際情況是:
「答案還沒準備好」
所以只能看到:
👉 Promise { <pending> }
八、正確寫法(一定要 await)
1 | async function fn() { |
意思是:
「我願意等你一下」
九、async / await 常見錯誤(新手必踩)
❌ 忘記加 async
1 | function fn() { |
👉 不能用 await
❌ 忘記加 await
1 | async function fn() { |
👉 還是在等
❌ await 不能等 setTimeout
1 | await setTimeout(...) |
因為:
setTimeout不是 Promise
十、為什麼函式宣告方式很重要?
1 | fn(); // ❌ |
因為:
- 箭頭函式不會被提前準備好
正確方式:
1 | async function fn() {} |
十一、IIFE:立刻執行的小技巧
1 | (async () => { |
意思是:
「我不想取名字,我只想現在跑」
十二、為什麼一定要 try / catch?
因為:
- async 裡面只要出錯
- 後面全部不跑
1 | try { |
👉 好習慣,一定要寫
十三、Axios 是什麼?
Axios 是:
- 幫你跟後端要資料
- 已經包成 Promise
- 非常好搭配 async / await
十四、前後端在幹嘛?(超白話)
- 前端:畫畫面、按按鈕
- 後端:算資料、存資料
流程像:
1 | 你 → 前端 → 後端 → 前端 → 顯示給你看 |
評論
匿名评论隐私政策










