国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

深入理解Node.js 事件循環和回調函數

2019-11-20 08:36:34
字體:
來源:轉載
供稿:網友

本文詳細的介紹了Node.js 事件循環和Node.js回調函數,廢話不多說了,具體看下面把。

 一、Node.js 事件循環

Node.js 是單進程單線程應用程序,但是通過事件和回調支持并發,所以性能非常高。Node.js 的每一個 API 都是異步的,并作為一個獨立線程運行,使用異步函數調用,并處理并發。Node.js 基本上所有的事件機制都是用設計模式中觀察者模式實現。Node.js 單線程類似進入一個while(true)的事件循環,直到沒有事件觀察者退出,每個異步事件都生成一個事件觀察者,如果有事件發生就調用該回調函數.

1、事件驅動程序

Node.js 使用事件驅動模型,當web server接收到請求,就把它關閉然后進行處理,然后去服務下一個web請求。當這個請求完成,它被放回處理隊列,當到達隊列開頭,這個結果被返回給用戶。這個模型非常高效可擴展性非常強,因為web server一直接受請求而不等待任何讀寫操作。(這也被稱之為非阻塞式IO或者事件驅動IO)。在事件驅動模型中,會生成一個主循環來監聽事件,當檢測到事件時觸發回調函數。

整個事件驅動的流程就是這么實現的,非常簡潔。有點類似于觀察者模式,事件相當于一個主題(Subject),而所有注冊到這個事件上的處理函數相當于觀察者(Observer)。Node.js 有多個內置的事件,我們可以通過引入 events 模塊,并通過實例化 EventEmitter 類來綁定和監聽事件,如下實例:
  

 // 引入 events 模塊 var events = require('events'); // 創建 eventEmitter 對象 var eventEmitter = new events.EventEmitter(); 以下程序綁定事件處理程序: // 綁定事件及事件的處理程序 eventEmitter.on('eventName', eventHandler); 我們可以通過程序觸發事件: // 觸發事件 eventEmitter.emit('eventName'); 

2、實例

創建 main.js 文件,代碼如下所示:

// 引入 events 模塊 var events = require('events'); // 創建 eventEmitter 對象 var eventEmitter = new events.EventEmitter(); // 創建事件處理程序 var connectHandler = function connected() {   console.log('連接成功。');   // 觸發 data_received 事件   eventEmitter.emit('data_received'); } // 綁定 connection 事件處理程序 eventEmitter.on('connection', connectHandler); // 使用匿名函數綁定 data_received 事件 eventEmitter.on('data_received', function(){   console.log('數據接收成功。'); }); // 觸發 connection 事件 eventEmitter.emit('connection'); console.log("程序執行完畢。"); 

二、Node.js 回調函數

Node.js 異步編程的直接體現就是回調。異步編程依托于回調來實現,但不能說使用了回調后程序就異步化了。回調函數在完成任務后就會被調用,Node 使用了大量的回調函數,Node 所有 API 都支持回調函數。例如,我們可以一邊讀取文件,一邊執行其他命令,在文件讀取完成后,我們將文件內容作為回調函數的參數返回。這樣在執行代碼時就沒有阻塞或等待文件 I/O 操作。這就大大提高了 Node.js 的性能,可以處理大量的并發請求。

1、阻塞代碼實例

創建一個文件 test.txt ,內容如下:

Hello World! fs.readFileSync() fs.readFile() 

創建 test.js 文件, 代碼如下:

console.log('-------程序開始執行--------');  // 引入fs模塊 var fs = require("fs"); //同步讀取文件 var data = fs.readFileSync('test.txt','utf-8'); console.log(data.toString()); console.log('-------程序執行結束--------'); 

以上代碼執行結果如下:

2、非阻塞代碼實例

創建 test.js 文件, 代碼如下:

console.log('-------程序開始執行--------');  // 引入fs模塊 var fs = require("fs"); //異步讀取文件 fs.readFile('test.txt','utf-8',function (err, data) {   if (err) return console.error(err);   console.log(data.toString()); }); console.log('-------程序執行結束--------');  

以上程序中 fs.readFile() 是異步函數用于讀取文件。如果在讀取文件過程中發生錯誤,錯誤 err 對象就會輸出錯誤信息。如果沒發生錯誤,readFile 跳過 err 對象的輸出,文件內容就通過回調函數輸出。

以上代碼執行結果如下:
接下來我們刪除 input.txt 文件,執行結果如下所示:
 以上兩個實例我們了解了阻塞與非阻塞調用的不同。第一個實例在文件讀取完后才執行完程序。第二個實例我們不需要等待文件讀取完,這樣就可以在讀取文件時同時執行接下來的代碼,大大提高了程序的性能。因此,阻塞按是按順序執行的,而非阻塞是不需要按順序的,所以如果需要處理回調函數的參數,我們就需要寫在回調函數內。

三、fs.readFileSync和fs.readFile

1、s.readFileSync

語法:fs.readFileSync(filename, [encoding]) 

接收參數:

  filename:文件路徑

  options:option對象,包含 encoding,編碼格式,該項是可選的。

 由于Node.js僅支持如下編碼:utf8, ucs2, ascii, binary, base64, hex,并不支持中文GBK或GB2312之類的編碼,因此如果要讀寫GBK或GB2312格式的文件的中文內容,必須要用額外的模塊:iconv-lite。

2、fs.readFile

語法:fs.readFile(filename, [encoding], [callback(err,data)])

接收參數:

  filename:文件路徑

  options :option對象,包含 encoding,編碼格式,該項是可選的。

  callback :回調,傳遞2個參數 異常err 和 文件內容 data

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 墨脱县| 三亚市| 抚松县| 古蔺县| 太白县| 云梦县| 独山县| 衡山县| 渭南市| 双流县| 大足县| 安化县| 措美县| 绥德县| 都江堰市| 石景山区| 姜堰市| 文山县| 花莲县| 攀枝花市| 汤阴县| 青阳县| 津南区| 大安市| 邵阳县| 石家庄市| 翁源县| 乌拉特中旗| 鄂托克旗| 辽源市| 连云港市| 牡丹江市| 宣汉县| 阿荣旗| 昌吉市| 南靖县| 全州县| 益阳市| 兴山县| 黄石市| 利川市|