由于Javascript默認情況下是單線程的,這意味著代碼不能創建新的線程來并行執行。而Nodejs和JavaScript相差也不大,并且它還引入了非阻塞的 I/O ,從而將異步的概念擴展到了文件訪問、網絡調用等。因此在Nodejs中使用異步編程就是通過回調函數來實現。把回調函數作為參數傳遞進方法里,方法內部執行完畢后再執行回調函數。在Nodejs中使用了大量的回調函數,Node 所有 API 都支持回調函數。
function readFile(filePath, callback) {
// I/O 讀取文件底層邏輯
// ...
callback();
}
非阻塞寫法
const fs = require("fs");
fs.readFile('file.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log(data.toString());
});
console.log("read file end.");
這種寫法應當是先輸出 read file end. 的內容,然后才輸出文件里的內容。
阻塞寫法
const fs = require("fs");
const data = fs.readFileSync('file.txt');
console.log(data.toString());
console.log("read file end.");
而阻塞寫法是先輸出文件里的內容,然后才輸出 read file end. 的內容。
回調地獄
JavaScript的語法中,回調的設計有效的解決了同步處理的問題,但是如果每一層函數都要依賴回調函數的返回值來進行下一步的操作的時候,就會嵌套出很多層代碼,陷入這個回調地獄。這種代碼非常難維護和閱讀。
比如:
fs.readFile('file1.json', (err, data) => {
if (err !== null) {
fs.readFile('file2.json',(err,data) =>{
// ... callback
})
}
})