[JavaScript] 一次搞懂同步與非同步的一切:待會叫你 — 回呼函式(Callback Function)
全系列共四篇:
一、[JavaScript] 一次搞懂同步與非同步的一切:一次做幾件事情 - 同步(Sync)與非同步(Async)
二、[JavaScript] 一次搞懂同步與非同步的一切:待會叫你 - 回呼函式(Callback Function)
三、[JavaScript] 一次搞懂同步與非同步的一切:非同步解法救星 - Promise(ES6)
四、[JavaScript] 一次搞懂同步與非同步的一切:解法更進化 - Async/Await(ES7)
Outline:
+ 什麼是 Callback function?
+ 範例
什麼是 Callback function?
Callback function 又稱為回呼、回調、回叫函式,先來看看 w3c 怎麼說:
A callback is a function passed as an argument to another function.
callback 是一種可以當作是函式參數一樣被帶進其他函式的函式。
Callback function 其實就是一般的函式,差異只在 Callback function 是在指定時機才觸發的 function,你可以在指定的時候,做完某件事情的時候才呼較的函式,所以一句話來說,如本文標題,就像是:「待會叫你」。
上一篇說了 Javascript 的同步與非同步,在開發的時候,常常會需要控制程式發生的順序,funcA 跑完之後再執行 funcB,再執行 funcD…等,
Callback function 的用途就在於可以讓我們的程式在不論同步或是非同步執行的狀況下都還是可以依序執行函式。
先來看看在一般函式中,如果我們要帶入參數,會怎麼帶入呢?
Callback function 帶入的方式也是一樣的:
一步一步來看這段寫了些什麼:
- 定義一開始要呼叫的函式 sayHi,並將帶入的參數取名為 myCallback 並執行
- 定義函式 callme
- 執行 sayHi,並將函式 callme 帶入當作 sayHi 所需參數
所以這段執行碼在執行起來會是這樣:
- 執行了 sayHi 並帶入函式 callme 當作參數
- 在 sayHi 裡面拿到 callme 這個函式,執行 callme
- 得到 callme 的 console 結果「im back!」
結束了,就是這樣而已,或者要帶入其他參數也可以:
範例
知道了 callback 簡易的用法之後,再來看看幾個其實你已經用過 callback 的時候:
addEventListener
addEventListener 是對 DOM 綁定事件的時候很常見的方式,所以大概會像是這樣:
addEventListener 也是一種非同步的 WebAPIs,這樣的寫法意即點擊後觸發後面帶入的函式
setTimeout
在需要延遲發生事件的時候也很常使用到,基本寫法大概是:
等待了 1 秒之後,再執行了後面的 function。
如果要寫得比較像是上面的範例,把函式拉出來的話:
Http Request
接下來看一個原生的 Http Request 寫法:
在這裡我 call 了一支 GET 的 api,請求完成之後即會執行 function,所以 request.onload 後的 function 就是我的 Callback function。
回呼地獄 Callback Hell
講到 Callback function 的邏輯複雜、較難維護,Callback Hell 就是最佳的範例,意思就是包了無限多層的 callback,做完第一件事之後做第二件事,再做第三件事...下去:
很難閱讀,也很難維護,收到前人這樣的 code 可能會直接關機下班。
簡單來說,Callback 很好用,很常用,但是對於 Callback Hell、錯誤處理、非同步請求錯誤訊息,Callback 沒有辦法完美解決,解法在下一篇的 Promise 再詳盡說明。
看過很多網路上同步與非同步的文章,大部分都將這四個主題寫在一起,自己全部一起看總是容易看到出神,所以這次分為四篇文章,可能每篇的篇幅都不會太長,目的就是可以一次一次慢慢吸收,慢慢消化。
內容若有任何錯誤,歡迎留言交流指教!🌴全系列共四篇:
一、[JavaScript] 一次搞懂同步與非同步的一切:一次做幾件事情 - 同步(Sync)與非同步(Async)
二、[JavaScript] 一次搞懂同步與非同步的一切:待會叫你 - 回呼函式(Callback Function)
三、[JavaScript] 一次搞懂同步與非同步的一切:非同步解法救星 - Promise(ES6)
四、[JavaScript] 一次搞懂同步與非同步的一切:解法更進化 - Async/Await(ES7)