天天看點

Node.js學習筆記(四、回調函數)

回調函數

回調函數,也被稱為高階函數,是一個函數被作為參數傳遞給另一個函數。(主要搞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("程式執行結束");      

運作一下:

Node.js學習筆記(四、回調函數)
非阻塞執行個體

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("程式執行結束!");      
Node.js學習筆記(四、回調函數)

可以看到,阻塞執行個體是按照順序執行的,而非阻塞執行個體不是按照順序執行的。

第一個執行個體在檔案讀取完後才執行完程式。 第二個執行個體我們不需要等待檔案讀取完,這樣就可以在讀取檔案時同時執行接下來的代碼,大大提高了程式的性能。

如果想需要處理回調函數的參數,我們就需要寫在回調函數内。

參考:

【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