剛開始學習javascript時,對回調函數的理解僅僅停留在知道定義階段。什麼是回調函數? 就是將一個函數做爲參數傳遞給另外一個函數,做爲參數的這個函數就是回調函數。 至於爲何要用到回調函數?回調函數有什麼做用? 當時對這些一無所知! 最近學習node.js涉及到了大量的異步編程,不少地方都須要用到回調函數,因此這兩天深刻了解了JavaScript的回調函數,下面是我對回調函數的理解。javascript
想要弄明白js回調函數,首先要清楚函數的規則,在javascript中函數是一個對象,準確的來講函數是用function()構造函數建立的一個function對象,所以咱們能夠將函數存儲在變量中,固然也就能夠將存儲在變量中的函數做爲一個參數傳遞給另外一個函數,這就是回調函數。
舉個例子:html
var callback = function(arg3) { console.log('callback Totle is:' + arg3) } function fn(arg1, arg2, cb) { var Total = arg1 + arg2; cb(Total); console.log('mainFunction Totle is:' + Total) } fn(2, 2, callback) // 調用fn()函數,並傳入2, 2, callback做爲參數
上面例子中咱們將一個匿名函數賦值給變量callback,同時將callback做爲參數傳遞給了fn()函數,這時在函數fn()中callback就是回調函數。java
上面的代碼執行結果爲:node
callback Totle is:4 mainFunction Totle is:4
不對啊! 回調函數不是應該在主函數的最後執行嗎?
對,不少介紹回調函數的例子講到這裏是就完了,異步回調函數的確是應該在函數的最後執行,不過上面的例子是一個同步回調函數,函數的執行順序依然自上而下順序執行。 那麼什麼是異步回調呢? 咱們又怎麼實現異步回調呢? 下面咱們舉兩個例子來講明:編程
示例1:網絡
function f2() { console.log('f2 finished') } function f1(cb) { setTimeout(cb,1000) //用setTimeout()模擬耗時操做 console.log('f1 finished') } f1(f2); //獲得的結果是 f1 finished ,f2 finished
這裏咱們用setTimeout()來模擬耗時操做的前提是js中的setTimeout()函數支持異步處理,因此咱們獲得的結果是 f1 finished ,f2 finishedapp
示例2:異步
var fs = require("fs"); fs.readFile('input.txt','utf-8', function (err, data) { if (err) return console.error(err); console.log(data.toString()); }); console.log("程序執行結束!");
程序執行的結果是:async
$ node app 程序執行結束! 咱們來測試一下異步回調函數
上面例子中咱們先建立了一個文件input.txt,裏面的內容是:'咱們來測試一下異步回調函數'
若是按照同步的思惟,程序應該執行fs.readFile,直到文件讀完以後才執行後面的console.log("程序執行結束!"); 然而node中的fs.readFile是支持異步處理的,所以程序執行到這兒的時候並不會阻塞,而是繼續向後執行,當文件讀取完畢以後再自動調用傳入的匿名回調函數,所以出現了上面的結果。異步編程
參考文章:
詳解回調函數——以JS爲例解讀異步、回調和EventLoop http://blog.csdn.net/tywinsta...
Javascript異步編程的4種方法 - 阮一峯的網絡日誌http://www.ruanyifeng.com/blo...