欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Node.js事件的正確使用方法

 更新時(shí)間:2019年04月05日 09:32:36   作者:瘋狂的技術(shù)宅  
這篇文章主要給大家介紹了關(guān)于Node.js事件的正確使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Node.js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

事件驅(qū)動(dòng)的編程變得流行之前,在程序內(nèi)部進(jìn)行通信的標(biāo)準(zhǔn)方法非常簡(jiǎn)單:如果一個(gè)組件想要向另外一個(gè)發(fā)送消息,只是顯式地調(diào)用了那個(gè)組件上的方法。但是在 react 中用的卻是事件驅(qū)動(dòng)而不是調(diào)用。

事件的好處

這種方法能夠使組件更加分離。在我們繼續(xù)寫程序時(shí),會(huì)識(shí)別整個(gè)過程中的事件,在正確的時(shí)間觸發(fā)它們,并為每個(gè)事件附加一個(gè)或多個(gè)事件監(jiān)聽器,這使得功能擴(kuò)展變得更加容易。我們可以為特定事件添加更多的 listener,而不必修改現(xiàn)有的偵聽器或觸發(fā)事件的應(yīng)用程序部分。我們所談?wù)摰氖怯^察者模式。

設(shè)計(jì)一個(gè)事件驅(qū)動(dòng)的體系結(jié)構(gòu)

對(duì)事件進(jìn)行識(shí)別非常重要,我們不希望最終必須從系統(tǒng)中刪除或替換現(xiàn)有事件,因?yàn)檫@可能會(huì)迫使我們刪除或修改附加到事件上的眾多偵聽器。我的一般原則是僅在業(yè)務(wù)邏輯單元完成執(zhí)行時(shí)才考慮觸發(fā)事件。

假如你想在用戶注冊(cè)后發(fā)送一堆不同的電子郵件。注冊(cè)過程本身可能會(huì)涉及許多復(fù)雜的步驟和查詢,但從商業(yè)角度來看,這只是其中的一個(gè)步驟。每個(gè)要發(fā)送的電子郵件也是單獨(dú)的步驟。因此,一旦注冊(cè)完成馬上就發(fā)布事件是很有意義的。于是我們附加了多個(gè)監(jiān)聽器,每個(gè)監(jiān)聽器負(fù)責(zé)發(fā)送一種類型的電子郵件。

Node的異步事件驅(qū)動(dòng)架構(gòu)具有一些被稱為“emitters”的對(duì)象。它們發(fā)出命名事件,這些事件會(huì)調(diào)用被稱為“l(fā)istener”的函數(shù)。發(fā)出事件的所有對(duì)象都是 EventEmitter 類的實(shí)例。使用它,我們可以創(chuàng)建自己的事件:

一個(gè)例子

讓我們使用內(nèi)置的 events 模塊(我建議你查看這個(gè)文檔:https://nodejs.org/api/events...)以獲取對(duì) EventEmitter 的訪問權(quán)限。

const EventEmitter = require('events');

const myEmitter = new EventEmitter();

module.exports = myEmitter;

這是我們的服務(wù)器端程序的一部分,它負(fù)責(zé)接收HTTP請(qǐng)求,保存新用戶并發(fā)出事件:

const myEmitter = require('./my_emitter');

// Perform the registration steps

// Pass the new user object as the message passed through by this event.
myEmitter.emit('user-registered', user);

附加一個(gè)監(jiān)聽器的單獨(dú)模塊:

const myEmitter = require('./my_emitter');

myEmitter.on('user-registered', (user) => {
 // Send an email or whatever.
});

將策略與實(shí)現(xiàn)分開是一種非常好的做法。在這種情況下,策略意味著哪些 listener 訂閱了哪些事件。實(shí)現(xiàn)意味著 listener 自己。

const myEmitter = require('./my_emitter');
const sendEmailOnRegistration = require('./send_email_on_registration');
const someOtherListener = require('./some_other_listener');

myEmitter.on('user-registered', sendEmailOnRegistration);
myEmitter.on('user-registered', someOtherListener);
module.exports = (user) => {
 // Send a welcome email or whatever.
}

這種分離使 listener 也可以被重復(fù)使用,它可以被附加到發(fā)送相同消息的其他事件上(用戶對(duì)象)。同樣重要的是 當(dāng)多個(gè) listener 被附加到單個(gè)事件時(shí),它們將按照附加的順序同步執(zhí)行。因此 someOtherListener 將在 sendEmailOnRegistration 完成執(zhí)行后運(yùn)行。

但是,如果你希望自己的 listener 以異步方式運(yùn)行,只需用 setImmediate 包裝它們的實(shí)現(xiàn),如下所示:

module.exports = (user) => {
 setImmediate(() => {
 // Send a welcome email or whatever.
 });
}

讓你的 Listeners 保持簡(jiǎn)潔

在寫 listener 時(shí)要堅(jiān)持單一責(zé)任原則。一個(gè) listener 應(yīng)該只做一件事并把事情做好。例如:要避免在 listener 中編寫太多的條件并根據(jù)事件傳來的數(shù)據(jù)(消息)去決定做什么。在這種情況下使用不同的事件會(huì)更加合適:

const myEmitter = require('./my_emitter');

// Perform the registration steps

// The application should react differently if the new user has been activated instantly.
if (user.activated) {
 myEmitter.emit('user-registered:activated', user);
 
} else {
 myEmitter.emit('user-registered', user);
}
const myEmitter = require('./my_emitter');
const sendEmailOnRegistration = require('./send_email_on_registration');
const someOtherListener = require('./some_other_listener');
const doSomethingEntirelyDifferent = require('./do_something_entirely_different');


myEmitter.on('user-registered', sendEmailOnRegistration);
myEmitter.on('user-registered', someOtherListener);

myEmitter.on('user-registered:activated', doSomethingEntirelyDifferent);
view raw

必要時(shí)明確分離 Listener

在前面的例子中,我們的 listener 是完全獨(dú)立的函數(shù)。但是在 listener 與對(duì)象關(guān)聯(lián)的情況下(這時(shí)是一種方法),必須手動(dòng)將其從已訂閱的事件中分離出來。否則對(duì)象將永遠(yuǎn)不會(huì)被垃圾回收,因?yàn)閷?duì)象( listener )的一部分將會(huì)繼續(xù)被外部對(duì)象( emitter )引用,所以存在內(nèi)存泄漏的可能。

例如,如果我們正在開發(fā)一個(gè)聊天程序,并且希望當(dāng)新消息到達(dá)用戶進(jìn)入的聊天室時(shí),顯示通知的功能應(yīng)該位于該用戶對(duì)象本身的內(nèi)部,我們可能會(huì)這樣做:

class ChatUser {
 
 displayNewMessageNotification(newMessage) {
 // Push an alert message or something.
 }
 
 // `chatroom` is an instance of EventEmitter.
 connectToChatroom(chatroom) {
 chatroom.on('message-received', this.displayNewMessageNotification);
 }

 disconnectFromChatroom(chatroom) {
 chatroom.removeListener('message-received', this.displayNewMessageNotification);
 }
}

當(dāng)用戶關(guān)閉他的標(biāo)簽或暫時(shí)斷開互聯(lián)網(wǎng)連接時(shí),我們可能希望在服務(wù)器端發(fā)起一個(gè)回調(diào),通知其他用戶有人剛剛下線。當(dāng)然在這時(shí)為脫機(jī)用戶調(diào)用 displayNewMessageNotification 沒有任何意義。除非我們刪除它,否則它將繼續(xù)被用于調(diào)用新消息。如果不這樣做,除了不必要的調(diào)用之外,用戶對(duì)象也會(huì)被永久地保留在內(nèi)存中。因此在用戶脫機(jī)時(shí)應(yīng)該在服務(wù)器端回調(diào)中調(diào)用 disconnectFromChatroom。

注意事項(xiàng)

如果不小心,即便是松散耦合的事件驅(qū)動(dòng)架構(gòu)也會(huì)導(dǎo)致復(fù)雜性的增加,可能會(huì)導(dǎo)致在系統(tǒng)中跟蹤依賴關(guān)系變得很困難。如果我們從偵聽器內(nèi)部發(fā)出事件,程序會(huì)特別容易出現(xiàn)這類問題。這可能會(huì)觸發(fā)意外的事件鏈。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • 使用Node.js搭建Vue項(xiàng)目的詳細(xì)步驟

    使用Node.js搭建Vue項(xiàng)目的詳細(xì)步驟

    Vue.js 是一款流行的 JavaScript 框架,而 Node.js 提供了一個(gè)強(qiáng)大的運(yùn)行環(huán)境,兩者的結(jié)合使得開發(fā)者可以輕松構(gòu)建現(xiàn)代化的前端項(xiàng)目,本文將介紹如何使用 Node.js 搭建一個(gè)基本的 Vue 項(xiàng)目,需要的朋友可以參考下
    2023-12-12
  • Nodejs Buffer的使用及Stream流和事件機(jī)制詳解

    Nodejs Buffer的使用及Stream流和事件機(jī)制詳解

    這篇文章主要為大家介紹了Nodejs Buffer的使用及Stream流和事件機(jī)制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 通過nodejs 服務(wù)器讀取HTML文件渲染到頁(yè)面的方法

    通過nodejs 服務(wù)器讀取HTML文件渲染到頁(yè)面的方法

    今天小編就為大家分享一篇通過nodejs 服務(wù)器讀取HTML文件渲染到頁(yè)面的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Node.js多進(jìn)程的方法與參數(shù)實(shí)例說明

    Node.js多進(jìn)程的方法與參數(shù)實(shí)例說明

    這篇文章主要介紹了Node.js多進(jìn)程的方法與參數(shù)實(shí)例說明,Node.js 是以單線程的模式運(yùn)行的,但它使用的是事件驅(qū)動(dòng)來處理并發(fā),這樣有助于我們?cè)诙嗪?nbsp;cpu 的系統(tǒng)上創(chuàng)建多個(gè)子進(jìn)程,從而提高性能,需要的朋友可以參考下
    2023-05-05
  • node.js中的fs.writeFile方法使用說明

    node.js中的fs.writeFile方法使用說明

    這篇文章主要介紹了node.js中的fs.writeFile方法使用說明,本文介紹了fs.writeFile的方法說明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • nodejs操作mongodb的增刪改查功能實(shí)例

    nodejs操作mongodb的增刪改查功能實(shí)例

    這篇文章主要介紹了nodejs操作mongodb的增刪改查功能,簡(jiǎn)單分析了mongodb模塊的安裝并結(jié)合實(shí)例形式分析了nodejs操作mongodb數(shù)據(jù)庫(kù)進(jìn)行增刪改查的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-11-11
  • Node.js模塊全局安裝路徑配置方法

    Node.js模塊全局安裝路徑配置方法

    今天小編就為大家分享一篇Node.js模塊全局安裝路徑配置方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • 詳解用node搭建簡(jiǎn)單的靜態(tài)資源管理器

    詳解用node搭建簡(jiǎn)單的靜態(tài)資源管理器

    本篇文章主要介紹了詳解用node搭建簡(jiǎn)單的靜態(tài)資源管理器,主要用node的fs模塊,自己手寫一個(gè)簡(jiǎn)單的靜態(tài)資源管理器。有興趣的可以了解一下
    2017-08-08
  • node?NPM庫(kù)qs?iconv-lite字符串編碼轉(zhuǎn)換及解析URL查詢學(xué)習(xí)

    node?NPM庫(kù)qs?iconv-lite字符串編碼轉(zhuǎn)換及解析URL查詢學(xué)習(xí)

    這篇文章主要為大家介紹了node?NPM庫(kù)之qs解析URL查詢字符串及iconv-lite字符串編碼轉(zhuǎn)換學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Node.js操作mysql數(shù)據(jù)庫(kù)增刪改查

    Node.js操作mysql數(shù)據(jù)庫(kù)增刪改查

    這篇文章主要介紹使用Node.js操作mysql數(shù)據(jù)庫(kù)增刪改查的相關(guān)資料,需要的朋友可以參考下
    2016-03-03

最新評(píng)論