某些JS提供的函式是非同步的:
1. setTimeout
2. DOM 事件裡的event listener 💗
3. 各種 callback function
forEach(callbackFn)
forEach(callbackFn, thisArg)
其他非同步:
1. mongoose 提供的 Model.create() 建立使用者資料,典型的非同步操作
setTimeout(function, delayTime)
- 第一個參數是 callback function,也就是「計時完成時,想要執行的函式」
第二個參數是延遲時間,單位是毫秒 (千分之一秒),3000 為 3 秒,以此類推。
- 要注意:當 setTimeout 被呼叫時,負責計時的是瀏覽器,JavaScript 執行環境 (runtime) 將計時工作交辦給瀏覽器以後,就繼續進行自己的動作,等瀏覽器把事情辦完以後,再把 callback function 丟回 runtime 中執行。
正因為 JavaScript 把計時工作發包出去了!所以在 setTimeout 裡的程式碼會延遲執行。
setTimeout(() => {
console.log('hello')
}, 500)
console.log('world')
先印出world在印出hello
3種方法,印出 hello world
1:把程式碼拉進同一個流程
setTimeout(() => {
console.log('hello')
// move here
console.log('world')
}, 500)
2:第二種解法是設定另一組時間,時間間距 絕對數值強制設定執行順序。
(workaround: 無法釐清code順序發生的問題和原因時可使用)
setTimeout(() => {
console.log('hello')
}, 500)
setTimeout(() => {
console.log('world')
}, 800)
3:callback 裡的 callback
在解法二中,用 500s 和 800s 絕對數值來強制設定執行順序。但實務上比較難這樣把時間確定下來。因此也有可能用 雙層的結構 來控制順序:
setTimeout(() => {
console.log('hello')
setTimeout(() => {
console.log('world')
}, 0)
}, 0)
解法三看起來跟解法一有點像,但是本質上不太一樣, 這個雙層結構確保了 callback function 的排隊順序:
理解順序的方式不是「由上而下」,而是「由外而內」。
JavaScript 只是擅長用非同步的方式在不同事情間「切換」,它的本質仍然是一次執行一件事 (single thread)。