Node.js原理阻塞和EventEmitter及其繼承的運用實戰

基本概念

簡單地說,Node.js是在服務器端運行的JavaScript。 節點。

$ node

> console.log('Hello 黎燃!');
Hello 黎燃!

然而,對於node JS,概念完全不同。

使用node JS,我們不僅實現瞭一個應用程序,還實現瞭整個HTTP服務器。

事實上,我們的web應用程序和相應的web服務器基本相同。 讓我們瞭解一下node JS應用程序由以下部分組成: 1.介紹所需模塊:我們可以使用require命令加載node JS模塊。 2.創建服務器:服務器可以監聽客戶端的請求,類似於Apache和nginx等HTTP服務器。 3.接收請求並響應請求的服務器很容易創建。客戶端可以使用瀏覽器或終端發送HTTP請求,服務器收到請求後返回響應數據。

回調函數

Node.jsS異步編程的直接體現是回調。

阻塞代碼

異步編程依賴於回調,但不能說在使用回調後程序將是異步的。 完成任務後將調用回調函數。節點使用大量回調函數。 節點的所有API都支持回調函數。

讀取文件後,我們返回文件內容作為回調函數的參數。 這樣,在執行代碼時就不會阻塞或等待文件I/O操作。

回調函數通常顯示為函數的最後一個參數:

function foo1(name, age, callback) { }
function foo2(value, callback1, callback2) { }

創建主JS文件,代碼如下:

var fs = require("fs");

var data = fs.readFileSync('input.txt');

console.log(data.toString());
console.log("程序執行結束!");

非阻塞代碼

創建主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 事件循環

 Node.js使用事件驅動模型。 當web服務器接收到一個請求時,它會關閉並處理該請求,然後為下一個web請求提供服務。 當請求完成時,它將被放回處理隊列。當它到達隊列的開頭時,結果將返回給用戶。 引入 events 模塊

var events = require('events');

創建 eventEmitter 對象

var eventEmitter = new events.EventEmitter();

綁定事件及事件的處理程序

eventEmitter.on('eventName', eventHandler);

觸發事件

eventEmitter.emit('eventName');

Node 應用程序工作原理

創建主JS文件,代碼如下:

var fs = require("fs");

fs.readFile('input.txt', function (err, data) {
   if (err){
      console.log(err.stack);
      return;
   }
   console.log(data.toString());
});
console.log("程序執行完畢");

在上述程序中,FS Readfile()是一個用於讀取文件的異步函數。如果在讀取文件期間發生錯誤,error err對象將輸出錯誤消息。

程序執行完畢

如果沒有發生錯誤,readfile將跳過err對象的輸出,並通過回調函數輸出文件內容。

接下來,我們刪除輸入Txt文件。

執行結果如下:

程序執行完畢 Error: ENOENT, open 'input.txt'

EventEmitter 類

每次有新連接時,服務器對象的net將觸發事件,而readstream對象的FS將在文件打開時觸發事件。所有生成事件的對象都是EventEmitter實例中的事件。

引入 events 模塊

var events = require('events');

創建 eventEmitter 對象

var eventEmitter = new events.EventEmitter();

如果在實例化EventEmitter對象期間發生錯誤,將觸發錯誤事件。添加新偵聽器時,將觸發newlistener事件。刪除偵聽器時,將觸發RemovelListener事件。

var EventEmitter = require('events').EventEmitter; 
var event = new EventEmitter(); 
event.on('some_event', function() { 
    console.log('some_event 事件觸發'); 
}); 
setTimeout(function() { 
    event.emit('some_event'); 
}, 1000); 

運行此代碼,控制臺在1秒_事件觸發器後輸出'some'。 觸發事件時,將依次調用註冊到此事件的事件偵聽器,並將事件參數作為回調函數參數傳遞。

var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.on('someEvent', function(arg1, arg2) { 
    console.log('listener1', arg1, arg2); 
}); 

on(event, listener)

註冊指定事件的偵聽器,並接受字符串事件和回調函數。

server.on('connection', function (stream) {
  console.log('someone connected!');
});

繼承 EventEmitter

大多數時候,我們不直接使用EventEmitter,而是在對象中繼承它。 所有支持事件響應的核心模塊,包括FS、net和HTTP,都是EventEmitter的子類。

  • 1.首先,具有實體函數的對象實現瞭符合語義的事件。事件的偵聽和發生應該是對象的一種方法。
  • 2.其次,JavaScript的對象機制是基於原型的,支持部分多重繼承。繼承EventEmitter不會幹擾對象的原始繼承關系。

到此這篇關於Node.js原理對於阻塞和EventEmitter及其繼承的運用實戰的文章就介紹到這瞭,更多相關Node.js EventEmitter 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: