Jun
appxtech
Published in
6 min readJul 16, 2020

--

什麼是Callback函式 (Callback function)

什麼是CallBack function?這個問題可能會在程式設計相關工作的面試中被問到,或是在某些文章或書籍中看過相關的介紹,但到底什麼是CallBack function?

下面就以自己現在學習的心得,來小小的講解一下CallBack function吧。

先從名詞的解釋開始,CallBack又稱為回調、回函、回呼函式,光是這個翻譯就看不懂了,在這邊我將CallBack的定義解釋為:在某一函式執行時或執行後,依條件或依序去執行所傳遞進來的函式

簡單的來說,就是

一個程式執行完再去執行另一個程式

為了能更清楚知道如何使用CallBack Function,我自己定義了二項CallBack的必要條件

1、讓函式成為另一個函式的參數

2、讓函式控制參數函式的執行時機

接下來會各別用例子來說明條件的內容

1、讓函式成為另一個函式的參數

上圖正確的執行了A()與B(),但若要成為CallBack Function的話,就必需要把要執行的函式,變成另一個函式的參數去執行。如下圖:

上圖會發現第24行,B function被A()以參數的方式傳入到function A()裡去,因此在15行的Fn指的就是B function。這時執行B()的控制並不是由主程式去執行,而是在A function裡去執行。

2、讓函式控制參數函式使用的時機

或許有人會想,在A函式裡去傳遞B函式再執行,不就和執行A函式後再執行B函式是一樣的嗎?為何又要使用CallBack。這是因為有可能會發生主程式執行函式時,會有等待的時間或延遲的問題,這樣便會影響到函式的執行順序錯誤的情況發生,以下用執行的結果來做說明。

上圖是正常情況下,主程式會依序執行的結果,因此從console來看,執行的順序是對的,但如果是下面的程式執行的結果呢?

發現了嗎?從console來看,執行的結果順序改變了!程式30行-32行的執行順序並沒有變,但在程式16行多了setTimeout。setTimeout 這個函式是讓所需要的執行的內容,延遲一下(毫秒)。而程式當執行到setTimeout時,會先跳過該程式,把執行的順序優先讓給下一個函式。這樣的好處是其他的函式不會因為需要等待而影響執行的時間。講簡單一點,不要讓整個網頁因為一個函式都因為等待而變慢,這樣使用者才不會覺的網頁很慢或很卡。

因此為了解決當一遇到函式需要等待,但其他函式又與該等待的函式有關連時,就會使用CallBack Function的時機點來處理。

從上圖來看,程式第31行執行A()中,帶入了B()與C()當作參數傳入,以確保15行在執行完A()後,才會去執行B(),也在執行完B()之後才會執行到C()。透,這樣一層一層的去執行,就能確定每個函式所執行的時機順序。

上述的範例解釋了CallBack的條件。1、讓函式成為另一個函式的參數2、讓函式控制參數函式使用的時機。接下來講講使用CallBack的優缺點吧!

CallBack function的優點

個人覺的,使用CallBack function的好處,在於

1、確保程式時機與關連

2、便於維護

CallBack function經常使用在Ajax上,因為當需要向外部請求時,便會發生需要等待或時間延遲的情況。這時必需要等待Ajax回來的資訊才能做下一步的判斷以使用不同的function時,就可以使用到CallBack function。

而便於維護,是當今天函式需要調整時,可以有效的減少需要大範圍修改的機會。例如需要顯示「start」,在上圖程式的範例中要加入下列function時,整個程式需要做多少的修改??

function D(){
console.log("start");
}

只需要修改主函式就好

將A(B,C)這個函式當作一個參數傳送到D()裡,當執行完D()後,再執行該參數「A(B,C)」,這樣便不用去更改原本大部份的函式function,又可達到確定執行的順序。

CallBack function的缺點

每個程式設計師都有自己的風格,這稱之為code style。但若CallBack function的設計及使用不當,就有可能讓CallBack function 不易於使用。

一種是回呼地獄(Callback Hell)如下圖

這是個簡單使用CallBack判斷數字為空值到5之間的判斷式,多條件的過多層CallBack,會讓整個段函式不易閱讀也不好護維。另會造成閱讀與維護困難的例子如下:

過多的CallBack function參數及指向,會在閱讀與維護時,尋找程式的主控權步驟變的相當混亂。即使是有經驗的程式人員,在處理這樣的code style時,也需要花費相當的時間。因此盡量避免使用這類風格的寫法,以減少維護上的困難。

--

--