回調函數
回調函數,也被稱為高階函數,是一個函數被作為參數傳遞給另一個函數。(主要搞Java,第一次見這個概念。)
函數也是對象
在javascript中,函數是對象。确切地說,函數是用Function()構造函數建立的Function對象。Function對象包含一個字元串,字元串包含函數的javascript代碼。
//可以這樣建立函數
var fn = new Function("arg1", "arg2", "return arg1 * arg2;");
fn(2, 3); //6
傳遞函數作為回調
在下面的例子中,将一個匿名函數當作參數傳遞給了fn函數。
function fn(arg1, arg2, callback){
var num = Math.ceil(Math.random() * (arg1 - arg2) + arg2);
callback(num); //傳遞結果
}
fn(10, 20, function(num){
console.log("Callback called! Num: " + num);
}); //結果為10和20之間的随機數
這種機制在jquery中經常可以見到。
$("#btn_1").click(function() {
alert("Btn 1 Clicked");
});
為什麼要用回調函數
傳統函數以參數形式輸入資料,并且使用傳回語句傳回值。理論上,在函數結尾處有一個return傳回語句,結構上就是:一個輸入點和一個輸出點。這比較容易了解,函數本質上就是輸入和輸出之間實作過程的映射。
但是,當函數的實作過程非常漫長,是選擇等待函數完成處理,還是使用回調函數進行異步處理呢?這種情況下,使用回調函數變得至關重要,例如:AJAX請求。若是使用回調函數進行處理,代碼就可以繼續進行其他任務,而無需空等。實際開發中,經常在javascript中使用異步調用。
Node.js 回調函數
Node.js 異步程式設計的直接展現就是回調。
異步程式設計依托于回調來實作,但不能說使用了回調後程式就異步化了。
回調函數在完成任務後就會被調用,Node 使用了大量的回調函數,Node 所有 API 都支援回調函數。
阻塞代碼執行個體
建立一個input.txt檔案(用英文,免得亂碼):
If life knocks you down, don't worry, don't fell sad , it will knock Ground and Pound.
建立main.js,讀取檔案:
var fs=require("fs");
var data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("程式執行結束");
運作一下:
非阻塞執行個體
mainb.js:
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
if (err) return console.error(err);
console.log(data.toString());
});
console.log("程式執行結束!");
可以看到,阻塞執行個體是按照順序執行的,而非阻塞執行個體不是按照順序執行的。
第一個執行個體在檔案讀取完後才執行完程式。 第二個執行個體我們不需要等待檔案讀取完,這樣就可以在讀取檔案時同時執行接下來的代碼,大大提高了程式的性能。
如果想需要處理回調函數的參數,我們就需要寫在回調函數内。
參考:
【1】、
https://www.runoob.com/nodejs/nodejs-callback.html【2】、
https://www.jb51.net/article/54750.htm【3】、
https://www.w3cschool.cn/nodejs/nodejs-callback.html