網頁

2019/5/3

JavaScript 什麼是Callback函式 (Callback Function)?

Callback函式,亦稱回呼函式,簡單來說就是「在一支函式執行完後,才要執行的函式」。
A function that is to be executed after another function has finished executing.


例如一支函式doFirst(),在執行結束才要執行doLater(),這個doLater()就是一支callback函式。

var doFirst = function (callback) {
    console.log('do first...');
    callback(); // <---執行傳入的doLater()
}

/** callback function **/
var doLater = function () {
    console.log('do later...')
}
doFirst(doLater);

印出

do first...
do later...

或許你會問,這和下面有什麼不同?doLater()也是在doFirst()執行後才執行阿。

var doFirst = function () {
    console.log('do first...');
}

var doLater = function () {
    console.log('do later...')
}

doFirst();
doLater();

印出結果同上

do first...
do later...

但如果是下面這樣結果就不同了,原本doFirst()中直接印出"do first..."文字的工作改交由setTimeout()這個非同步(Asynchronous)程式處理。
setTimeout()的第一個參數為時間到時要被執行的程式,第二個參數為要延遲的時間(毫秒)。

var doFirst = function () {
    setTimeout(function() {
        console.log('do first...')
    }, 3000); // 非同步,3秒後才執行
}

var doLater = function () {
    console.log('do later...')
}

doFirst();
doLater();

印出結果,doLater()中的文字先被印出,隔3秒後才印出doFirst()中的文字。

do later...
// 間隔3秒
do first...

簡單解釋一下程式中同步與非同步的概念,
同步(Synchronous)是指程式必須等待前面的程式執行完才能執行。
非同步(Asynchronous)是指程式不須等待前面的程式執行完就能執行。

由於上面的setTimeout()是非同步,所以下面的doLater()不須等待doFirst()執行完就會先被執行了。

所以為了確保doLater()要在doFirst()中的setTimeout(...)中的do first...印出後才執行,所以我們需要將doLater()做為callback函式以參數傳入doFirst()如下:

var doFirst = function (callback) {
    setTimeout(function() {
        console.log('do first...');
        callback(); // <-- 在"do first..."印出後才執行
    }, 3000); // 非同步,3秒後才執行
}

var doLater = function () {
    console.log('do later...')
}

doFirst(doLater);

印出結果,你可以看到程式會先等待3秒,然後才依序印出"do fisrt..."和"do later..."文字。

// 間隔3秒
do first...
do later...

因此Callback function的做用是保證一支程式確實會在一支程式執行後才執行。

至於被傳入callback函式的函式,也就是上面的doFirst(callback),又稱為Higher Order Function(高階函式)


所以對照文章開頭的說明,Callback函式應該這樣解釋比較好:
「以參數型態傳入另一個函式的函式」;
A function is passed to another function as an argument.

若文章對您有幫助還幫忙點個廣告,謝謝您的支持。


9 則留言:

  1. 很簡潔明瞭的文章 連同步非同步都有易懂的講解

    回覆刪除
  2. 清楚明瞭的解釋!非常感謝,覺得很受用。

    回覆刪除
  3. 非常簡單明瞭好懂,找了很多篇文章都看不懂,看了您的文章終於搞懂了什麼事callback function,非常感謝

    回覆刪除
  4. 肉豬大大真的是淺顯易懂的說明

    回覆刪除
  5. 這是我看過最清楚的Callback function講解,讚讚!

    回覆刪除
  6. 謝謝解釋,非常清楚!

    回覆刪除