了解 JavaScript 中的 callback function

前言

在初學 JavaScript 時,時常會聽到一個觀念:「callback function」,算是一個高頻詞彙。究竟 callback function 是什麼意思呢?

定義

根據 MDN 的說法,回呼函式(callback function)是指能藉由參數(argument)通往另一個函式的函式。它會在外部函式內調用、以完成某些事情。以下也是取自 MDN 的程式碼片段:

1
2
3
4
5
6
7
8
9
10
function greeting(name) {
alert('Hello ' + name)
}

function processUserInput(callback) {
var name = prompt('輸入你的名字:')
callback(name)
}

processUserInput(greeting) // 會印出 Hello, name(剛剛輸入的名字)

callback function 的特性

其實 callback function 並不是只有 JavaScript 才有的功能,其他像是 C、C++、Python 等語言都有支援 callback function 寫法。callback function 有這些特性:

一、支援 callback function 的語言,會支援把函式當作是第一公民 (first class)。有些程式語言並不支援把函式當作參數來傳遞,但 JavaScript 可以。JavaScript 把函式當作是第一公民,參數可以放入函式,所以 JavaScript 也支援 callback function 寫法。

二、callback hell。如果沒有管理好 callback function 寫法,很容易會造成程式碼多層巢嵌的慘況,導致程式碼難以閱讀與理解。常見的解決方案有使用 Promise 鏈式寫法,以及使用 async/await 來處理。

例子

在許多程式碼的設計中,時常會遇到 callback function 的使用。以下舉例一些例子

  1. setTimeout(callback, delayTime)
  2. domElement.addEventListener(event, callback)
  3. nodejs read file
  4. express middleware
1
2
3
4
5
6
7
// next 就是 callback function,用來告知 express 說這個路由想做的事情已經做完了
var app = express()

app.use(function (req, res, next) {
console.log('Time:', Date.now())
next()
})

小結

許多套件的 API,為了方便開發者能在某些事件完成後,能執行自己想要執行的程式,都會設計 callback function 讓開發者自訂。若是開發者自己開發程式的話,為了避免在處理非同步時產生的 callback hell,則可以考慮使用 Promise 與 async/await 來避免。

Reference