學(xué)習(xí) Node.js 一定要理解的內(nèi)容之一,文中主要涉及到了 EventEmitter 的使用和一些異步情況的處理,比較偏基礎(chǔ),值得一讀。
大多數(shù) Node.js 對(duì)象都依賴了 EventEmitter 模塊來監(jiān)聽和響應(yīng)事件,比如我們常用的 HTTP requests, responses, 以及 streams。
const EventEmitter = require('events');事件驅(qū)動(dòng)機(jī)制的最簡(jiǎn)單形式,是在 Node.js 中十分流行的回調(diào)函數(shù),例如 fs.readFile。 在回調(diào)函數(shù)這種形式中,事件每被觸發(fā)一次,回調(diào)就會(huì)被觸發(fā)一次。
我們先來探索下這個(gè)最基本的方式。
你準(zhǔn)備好了就叫我哈,Node!
很久很久以前,在 js 里還沒有原生支持 Promise,async/await 還只是一個(gè)遙遠(yuǎn)的夢(mèng)想,回調(diào)函數(shù)是處理異步問題的最原始的方式。
回調(diào)從本質(zhì)上講是傳遞給其他函數(shù)的函數(shù),在 JavaScript 中函數(shù)是第一類對(duì)象,這也讓回調(diào)的存在成為可能。
一定要搞清楚的是,回調(diào)在代碼中的并不表示異步調(diào)用。 回調(diào)既可以是同步調(diào)用的,也可以是異步調(diào)用的。
舉個(gè)例子,這里有一個(gè)宿主函數(shù) fileSize,它接受一個(gè)回調(diào)函數(shù) cb,并且可以通過條件判斷來同步或者異步地調(diào)用該回調(diào)函數(shù):
function fileSize (fileName, cb) { if (typeof fileName !== 'string') { // Sync return cb(new TypeError('argument should be string')); } fs.stat(fileName, (err, stats) => { if (err) { // Async return cb(err); } // Async cb(null, stats.size); });}這其實(shí)也是個(gè)反例,這樣寫經(jīng)常會(huì)引起一些意外的錯(cuò)誤,在設(shè)計(jì)宿主函數(shù)的時(shí)候,應(yīng)當(dāng)盡可能的使用同一種風(fēng)格,要么始終都是同步的使用回調(diào),要么始終都是異步的。
我們來研究下一個(gè)典型的異步 Node 函數(shù)的簡(jiǎn)單示例,它用回調(diào)樣式編寫:
const readFileAsArray = function(file, cb) { fs.readFile(file, function(err, data) { if (err) { return cb(err); } const lines = data.toString().trim().split('/n'); cb(null, lines); });};readFileAsArray 函數(shù)接受兩個(gè)參數(shù):一個(gè)文件路徑和一個(gè)回調(diào)函數(shù)。它讀取文件內(nèi)容,將其拆分成行數(shù)組,并將該數(shù)組作為回調(diào)函數(shù)的參數(shù)傳入,調(diào)用回調(diào)函數(shù)。
現(xiàn)在設(shè)計(jì)一個(gè)用例,假設(shè)我們?cè)谕荒夸浿械奈募?numbers.txt 包含如下內(nèi)容:
101112131415
如果我們有一個(gè)需求,要求統(tǒng)計(jì)該文件中的奇數(shù)數(shù)量,我們可以使用 readFileAsArray 來簡(jiǎn)化代碼:
readFileAsArray('./numbers.txt', (err, lines) => { if (err) throw err; const numbers = lines.map(Number); const oddNumbers = numbers.filter(n => n%2 === 1); console.log('Odd numbers count:', oddNumbers.length);});這段代碼將文件內(nèi)容讀入字符串?dāng)?shù)組中,回調(diào)函數(shù)將其解析為數(shù)字,并計(jì)算奇數(shù)的個(gè)數(shù)。
新聞熱點(diǎn)
疑難解答
圖片精選