如何正確使用Node.js中的事件

by Usama Ashraf

通過Usama Ashraf

如何正確使用Node.js中的事件 (How to use events in Node.js the right way)

Before event-driven programming became popular, the standard way to communicate between different parts of an application was pretty straightforward: a component that wanted to send out a message to another one explicitly invoked a method on that component. But event-driven code is written to react rather than be called.

在事件驅動的編程流行之前,在應用程序的不同部分之間進行通信的標準方法非常簡單:一個組件希望向另一個發出消息,而該組件顯式調用了該組件上的方法。 但是事件驅動的代碼是為了響應而不是被調用而編寫的。

比賽的好處 (The Benefits Of Eventing)

This approach causes our components to be much more decoupled. As we continue to write an application, we identify events along the way. We fire them at the right time and attach one or more event listeners to each one. Extending functionality becomes much easier. We can add on more listeners to a particular event. We are not tampering with the existing listeners or the part of the application where the event was fired from. What we’re talking about is the Observer pattern.

這種方法使我們的組件更加分離 。 在繼續編寫應用程序的過程中,我們一路確定事件。 我們在適當的時間解雇它們,并將一個或多個事件偵聽器附加到每個偵聽器擴展功能變得容易得多。 我們可以為特定事件添加更多的偵聽器。 我們不會篡改現有的偵聽器或觸發事件的應用程序部分。 我們正在談論的是觀察者模式。

設計事件驅動的體系結構 (Designing An Event-Driven Architecture)

Identifying events is pretty important. We don’t want to end up having to remove/replace existing events from the system. This might force us to delete/modify any number of listeners that were attached to the event. The general principle I use is to consider firing an event only when a unit of business logic finishes execution.

識別事件非常重要。 我們不想最終不得不從系統中刪除/替換現有事件。 這可能迫使我們刪除/修改附加到該事件的任意數量的偵聽器。 我使用的一般原則是僅在業務邏輯單元完成執行時才考慮觸發事件。

So say you want to send out a bunch of different emails after a user’s registration. Now, the registration process itself might involve many complicated steps, and queries. But from a business point of view, it is one step. And each of the emails to be sent out are individual steps as well. So it would make sense to fire an event as soon as registration finishes. We have multiple listeners attached to it, each responsible for sending out one type of email.

假設您要在用戶注冊后發送大量不同的電子郵件。 現在,注冊過程本身可能涉及許多復雜的步驟和查詢。 但是從業務角度來看,這只是一步。 而且,要發送的每封電子郵件都是單獨的步驟。 因此,在注冊完成后立即觸發事件是很有意義的。 我們具有多個偵聽器,每個偵聽器負責發送一種電子郵件。

Node’s asynchronous, event-driven architecture has certain kinds of objects called “emitters.” They emit named events which cause functions called “listeners” to be invoked. All objects that emit events are instances of the EventEmitter class. Using it, we can create our own events:

Node的異步事件驅動架構具有某些稱為“發射器”的對象。 它們發出命名事件,這些事件導致稱為“偵聽器”的函數被調用。 所有發出事件的對象都是EventEmitter類的實例。 使用它,我們可以創建自己的事件:

一個例子 (An Example)

Let’s use the built-in events module (which I encourage you to check out in detail) to gain access to EventEmitter.

讓我們使用內置的事件模塊(我建議您詳細檢查該模塊)來訪問EventEmitter

This is the part of the application where our server receives an HTTP request, saves a new user and emits an event:

這是服務器接收HTTP請求,保存新用戶并發出事件的應用程序的一部分:

And a separate module where we attach a listener:

還有一個單獨的模塊,我們在其中附加了一個偵聽器:

It’s a good practice to separate policy from implementation. In this case policy means which listeners are subscribed to which events. Implementation means the listeners themselves.

將政策與實施分開是一個好習慣 在這種情況下,策略意味著哪些偵聽器訂閱了哪些事件。 實現是指偵聽器本身。

This separation allows for the listener to become re-usable too. It can be attached to other events that send out the same message (a user object). It’s also important to mention that when multiple listeners are attached to a single event, they will be executed synchronously and in the order that they were attached. Hence someOtherListener will run after sendEmailOnRegistration finishes execution.

這種分離也使偵聽器也可以重用。 它可以附加到發出相同消息的其他事件(用戶對象)。 同樣重要的是要提到, 當多個偵聽器附加到一個事件時,它們將按照附加的順序同步執行 。 因此, someOtherListener將在sendEmailOnRegistration完成執行之后運行。

However, if you want your listeners to run asynchronously you can simply wrap their implementations with setImmediate like this:

但是,如果您希望監聽器異步運行,則可以使用setImmediate包裝它們的實現,如下所示:

保持聽眾干凈 (Keep Your Listeners Clean)

Stick to the Single Responsibility Principle when writing listeners. One listener should do one thing only and do it well. Avoid, for instance, writing too many conditionals within a listener that decide what to do depending on the data (message) that was transmitted by the event. It would be much more appropriate to use different events in that case:

編寫偵聽器時,請遵循“單一責任原則”。 一個聽眾應該只做一件事,并且做好。 例如,避免在偵聽器中編寫太多條件,以根據事件傳輸的數據(消息)來決定要做什么。 在這種情況下,使用不同的事件會更合適:

在必要時明確分離偵聽器 (Detaching Listeners Explicitly When Necessary)

In the previous example, our listeners were totally independent functions. But in cases where a listener is associated with an object (it’s a method), it has to be manually detached from the events it had subscribed to. Otherwise, the object will never be garbage-collected since a part of the object (the listener) will continue to be referenced by an external object (the emitter). Thus the possibility of a memory leak.

在前面的示例中,我們的偵聽器是完全獨立的功能。 但是,如果偵聽器與對象(這是一種方法)相關聯,則必須將其與已訂閱的事件手動分離。 否則,該對象將永遠不會被垃圾回收,因為該對象的一部分(偵聽器)將繼續被外部對象(發射器)引用。 因此存在內存泄漏的可能性。

For example, if we’re building a chat application and we want the responsibility for showing a notification when a new message arrives in a chat room that a user has connected to should lie within that user object itself, we might do this:

例如,如果我們正在構建一個聊天應用程序,并且我們希望當用戶連接到的新消息到達聊天室時,負責顯示通知的責任應該位于該用戶對象本身內,我們可以這樣做:

When the user closes his/her tab or loses their internet connection for a while, naturally, we might want to fire a callback on the server-side that notifies the other users that one of them just went offline. At this point, of course, it doesn’t make any sense for displayNewMessageNotification to be invoked for the offline user. It will continue to be called on new messages unless we remove it explicitly. If we don’t, aside from the unnecessary call, the user object will also stay in memory indefinitely. So be sure to call disconnectFromChatroom in your server-side callback that executes whenever a user goes offline.

當用戶關閉其選項卡或暫時失去其互聯網連接時,自然地,我們可能希望在服務器端觸發回調,以通知其他用戶其中一個剛下線。 當然,在這一點上,為脫機用戶調用displayNewMessageNotification沒有任何意義。 除非我們明確刪除它,否則它將繼續在新消息上被調用。 如果我們不這樣做,除了不必要的調用之外,用戶對象還將無限期地保留在內存中。 因此,請確保在用戶下線時執行的服務器端回調中調用disconnectFromChatroom

謹防 (Beware)

The loose coupling in event-driven architectures can also lead to increased complexity if we’re not careful. It can be difficult to keep track of dependencies in our system. Our application will become especially prone to this problem if we start emitting events from within listeners. This could possibly trigger chains of unexpected events.

如果我們不小心,事件驅動的體系結構中的松散耦合也會導致復雜性的增加。 跟蹤我們系統中的依賴關系可能很困難。 如果我們開始從偵聽器內部發出事件,我們的應用程序將特別容易出現此問題。 這可能會觸發一系列意外事件。

翻譯自: https://www.freecodecamp.org/news/using-events-in-node-js-the-right-way-fc50c060f23b/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/392897.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/392897.shtml
英文地址,請注明出處:http://en.pswp.cn/news/392897.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

你的成功有章可循

讀書筆記 作者 海軍 海天裝飾董事長 自我修煉是基礎。通過自我學習,在預定目標的指引下,將獲取的知識轉化為個人能力,形成自我規律,不斷循環,實現成功。 尋找和掌握規律,并熟練運用于實踐,是成功…

98k用計算機圖片,98K (HandClap)_譜友園地_中國曲譜網

《98K》文本歌詞98K之歌-HandClap-抖音 制譜:孫世彥這首《HandClap》是Fitz&TheTantrums樂隊演唱的一首歌曲,同時也是絕地求生中囂張BGM,是一首吃雞戰歌!這首歌譜曲者和填詞者都是三個人:JeremyRuzumna&#xff0c…

qt之旅-1純手寫Qt界面

通過手寫qt代碼來認識qt程序的構成,以及特性。設計一個查找對話框。以下是設計過程1 新建一個empty qt project2 配置pro文件HEADERS \Find.h QT widgetsSOURCES \Find.cpp \main.cpp3 編寫對話框的類代碼例如以下://Find.h #ifndef FIND_H #define F…

【隨筆】寫在2014年的第一天

想想好像就在不久前還和大家異常興奮地討論著世界末日的事,結果一晃也是一年前的事了。大四這一年,或者說整個2013年都是場搖擺不定的戲劇,去過的地方比前三年加起來還多的多,有時候也會恍惚地不知道自己現在在哪。簡單記幾筆&…

設計沖刺下載_如何運行成功的設計沖刺

設計沖刺下載by George Krasadakis通過喬治克拉薩達基斯(George Krasadakis) Design Sprints can generate remarkable output for your company — such as a backlog of impactful ideas, functional prototypes, learning and key insights from customers along with real…

leetcode 18. 四數之和(雙指針)

給定一個包含 n 個整數的數組 nums 和一個目標值 target,判斷 nums 中是否存在四個元素 a,b,c 和 d ,使得 a b c d 的值與 target 相等?找出所有滿足條件且不重復的四元組。 注意: 答案中不可以包含重…

WPF:從WPF Diagram Designer Part 4學習分組、對齊、排序、序列化和常用功能

在前面三篇文章中我們介紹了如何給圖形設計器增加移動、選擇、改變大小及面板、縮略圖、框線選擇和工具箱和連接等功能,本篇是這個圖形設計器系列的最后一篇,將和大家一起來學習一下如何給圖形設計器增加分組、對齊、排序、序列化等功能。 WPF Diagram D…

win7如何看計算機用戶名和密碼怎么辦,win7系統電腦查看共享文件夾時不顯示用戶名和密碼輸入窗口的解決方法...

win7系統使用久了,好多網友反饋說win7系統電腦查看共享文件夾時不顯示用戶名和密碼輸入窗口的問題,非常不方便。有什么辦法可以永久解決win7系統電腦查看共享文件夾時不顯示用戶名和密碼輸入窗口的問題,面對win7系統電腦查看共享文件夾時不顯…

ASP.NET Core跨域設置

項目中經常會遇到跨域問題,解決方法: 在appsettings.json 文件中添加json項 {"Logging": {"LogLevel": {"Default": "Warning"}},"AllowedHosts": "*","AppCores": "https…

微信客戶端<->騰訊微信服務器<->開發者服務器

出自 http://blog.csdn.net/hanjingjava/article/details/41653113 首先,通過Token驗證,將公眾號接入開發者服務器,這樣客戶端發給公眾號的信息會被轉發給開發者服務器; 第二,組裝微信特定消息格式,返回給用…

idea提高調試超時_如何提高您的調試技能

idea提高調試超時by Nick Karnik尼克卡尼克(Nick Karnik) 如何提高您的調試技能 (How to Improve Your Debugging Skills) All of us write code that breaks at some point. That is part of the development process. When you run into an error, you may feel that you do…

leetcode 834. 樹中距離之和(dp)

給定一個無向、連通的樹。樹中有 N 個標記為 0...N-1 的節點以及 N-1 條邊 。第 i 條邊連接節點 edges[i][0] 和 edges[i][1] 。返回一個表示節點 i 與其他所有節點距離之和的列表 ans。示例 1:輸入: N 6, edges [[0,1],[0,2],[2,3],[2,4],[2,5]] 輸出: [8,12,6,10,10,10] 解…

CSS設計指南(讀書筆記 - 背景)

本文轉自william_xu 51CTO博客,原文鏈接:http://blog.51cto.com/williamx/1140006,如需轉載請自行聯系原作者

在計算機網絡中 帶寬是什么,在計算機網絡中,“帶寬”用____表示。

答案查看答案解析:【解析題】計算機的發展經歷了4個時代,各個時代劃分的原則是根據()。【解析題】計算機網絡的最主要的功能是______。【解析題】馮.諾依曼提出的計算機工作原理為____。【解析題】計算機的通用性使其可以求解不同的算術和邏輯問題,這主要…

如何在iOS上運行React Native應用

by Soujanya PS通過Soujanya PS 如何在iOS上運行React Native應用 (How to run a React Native app on iOS) I recently started to develop a React-Native app on iOS. This was my first foray into native app development. I was surprised by the ease and level of abs…

導出excel 后 頁面按鈕失效(頁面假死)

在 page_load 里加上如下代碼:string beforeSubmitJS "\nvar exportRequested false; \n"; beforeSubmitJS "var beforeFormSubmitFunction theForm.onsubmit;\n"; beforeSubmitJS "theForm.onsubmit function(){ \n"; …

Mysql分組查詢group by語句詳解

(1) group by的含義:將查詢結果按照1個或多個字段進行分組,字段值相同的為一組(2) group by可用于單個字段分組,也可用于多個字段分組 select * from employee; --------------------------------------------- | num | d_id | name | age | sex | homea…

leetcode 75. 顏色分類(雙指針)

給定一個包含紅色、白色和藍色,一共 n 個元素的數組,原地對它們進行排序,使得相同顏色的元素相鄰,并按照紅色、白色、藍色順序排列。 此題中,我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。 注意: 不能使用代碼…

火車頭如何才能設置發布的時候,如果是有html代碼就直接的轉換掉,互聯網上笑話抽取及排重---火車頭采集器的使用和MD5算法的應用...

10011311341 呂濤、10011311356李紅目的:通過熟悉使用火車頭采集器,在網絡上采取3萬條笑話并進行排重,以此來熟悉web文本挖掘的一些知識。過程:本次學習,主要分成兩個部分。第一部分是笑話文本的采集,第二部…

Tcp_wrapper

在Linux進程分為:獨立進程和非獨立進程非獨立進程:是依賴于超級守護進程的進程, 且受Xinetd 管理,并在啟動服務時 必須啟動例子:#chkconfig –level 2345 telnetd on關與chkconfig 的命令:#chkconfig –lis…