国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

NodeJS Events 必知必會

bladefury / 2773人閱讀

摘要:超過會有警告輸出。實例默認的某個事件最大監聽者的數量,默認是。事件監聽數量是檢測內存泄露的一個標準一個維度。例如同一個實例類型事件個監聽者,類型事件個監聽者,這個并不會有告警。

1. 環境

node 8.11.3

2. 基本使用
// 01.js

const EventEmitter = require("events");

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on("event", () => {
  console.log("an event occurred!");
});
myEmitter.emit("event");

輸出:

an event occurred!
3. 傳參與this指向

emit()方法可以傳不限制數量的參數。

除了箭頭函數外,在回調函數內部,this會被綁定到EventEmitter類的實例上

// 02.js
const EventEmitter = require("events")

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()

myEmitter.on("event", function (a, b){
  console.log(a, b, this, this === myEmitter)
})

myEmitter.on("event", (a, b) => {
  console.log(a, b, this, this === myEmitter)
})

myEmitter.emit("event", "a", {name:"wdd"})

輸出:

a { name: "wdd" } MyEmitter {
  domain: null,
  _events: { event: [ [Function], [Function] ] },
  _eventsCount: 1,
  _maxListeners: undefined } true
a { name: "wdd" } {} false
4. 同步還是異步調用listeners?

emit()法會同步按照事件注冊的順序執行回調

// 03.js
const EventEmitter = require("events")

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()

myEmitter.on("event", () => {
  console.log("01 an event occurred!")
})

myEmitter.on("event", () => {
  console.log("02 an event occurred!")
})

console.log(1)
myEmitter.emit("event")
console.log(2)

輸出:

1
01 an event occurred!
02 an event occurred!
2

深入思考,為什么事件回調要同步?異步了會有什么問題?

同步去調用事件監聽者,能夠確保按照注冊順序去調用事件監聽者,并且避免競態條件和邏輯錯誤。

5. 如何只訂閱一次事件?

使用once去只訂閱一次事件

// 04.js
const EventEmitter = require("events")

class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()

let m = 0
myEmitter.once("event", () => {
  console.log(++m)
})
myEmitter.emit("event")
myEmitter.emit("event")
6. 不訂閱,就發飆的錯誤事件

error是一個特別的事件名,當這個事件被觸發時,如果沒有對應的事件監聽者,則會導致程序崩潰。

events.js:183
      throw er; // Unhandled "error" event
      ^

Error: test
    at Object. (/Users/xxx/github/node-note/events/05.js:12:25)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Function.Module.runMain (module.js:676:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3

所以,最好總是給EventEmitter實例添加一個error的監聽器

const EventEmitter = require("events")

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()

myEmitter.on("error", (err) => {
  console.log(err)
})

console.log(1)
myEmitter.emit("error", new Error("test"))
console.log(2)
7. 內部事件 newListener與removeListener

newListener與removeListener是EventEmitter實例的自帶的事件,你最好不要使用同樣的名字作為自定義的事件名。

newListener在訂閱者被加入到訂閱列表前觸發

removeListener在訂閱者被移除訂閱列表后觸發

// 06.js 
const EventEmitter = require("events")

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()

myEmitter.on("newListener", (event, listener) => {
  console.log("----")
  console.log(event)
  console.log(listener)
})

myEmitter.on("myEmitter", (err) => {
  console.log(err)
})

輸出:

從輸出可以看出,即使沒有去觸發myEmitter事件,on()方法也會觸發newListener事件。

----
myEmitter
[Function]
8. 事件監聽數量限制

myEmitter.listenerCount("event"): 用來計算一個實例上某個事件的監聽者數量

EventEmitter.defaultMaxListeners: EventEmitter類默認的最大監聽者的數量,默認是10。超過會有警告輸出。

myEmitter.getMaxListeners(): EventEmitter實例默認的某個事件最大監聽者的數量,默認是10。超過會有警告輸出。

myEmitter.eventNames(): 返回一個實例上又多少種事件

EventEmitter和EventEmitter實例的最大監聽數量為10并不是一個硬性規定,只是一個推薦值,該值可以通過setMaxListeners()接口去改變。

改變EventEmitter的最大監聽數量會影響到所有EventEmitter實例

該變EventEmitter實例的最大監聽數量只會影響到實例自身

如無必要,最好的不要去改變默認的監聽數量限制。事件監聽數量是node檢測內存泄露的一個標準一個維度。

EventEmitter實例的最大監聽數量不是一個實例的所有監聽數量。

例如同一個實例A類型事件5個監聽者,B類型事件6個監聽者,這個并不會有告警。如果A類型有11個監聽者,就會有告警提示。

如果在事件中發現類似的告警提示Possible EventEmitter memory leak detected,要知道從事件最大監聽數的角度去排查問題。

// 07.js
const EventEmitter = require("events")

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()

const maxListeners = 11

for (let i = 0; i < maxListeners; i++) {
  myEmitter.on("event", (err) => {
    console.log(err, 1)
  })
}

myEmitter.on("event1", (err) => {
  console.log(err, 11)
})

console.log(myEmitter.listenerCount("event"))
console.log(EventEmitter.defaultMaxListeners)
console.log(myEmitter.getMaxListeners())
console.log(myEmitter.eventNames())

輸出:

11
10
10
[ "event", "event1" ]
(node:23957) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 event listeners added. Use emitter.setMaxListeners() to increase limit

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97169.html

相關文章

  • 前端必知必會HTTP請求系列(二)簡單一點的HTTP協議

    摘要:通過請求和響應的交換達成通信協議中已經規定了請求是從客戶端發出,最后由服務端響應這個請求并返回。隨后的字符串指明了請求訪問的資源對象。協議自身不對請求和響應之間的通信狀態進行保存,也就是說這個級別。從前發送請求后需等待并受到響應。 showImg(https://segmentfault.com/img/bVbmDsG?w=1024&h=538); http協議用戶客戶端和服務器之間的...

    xbynet 評論0 收藏0
  • 前端必知必會HTTP請求系列(三)HTTP報文內的http信息

    摘要:報文用于協議交互的信息被稱為報文。現在出現的各種首部字段及狀態碼稍后會闡述。狀態碼響應報文包含了多個范圍的內容使用。如果服務器無法響應范圍請求,則會返回狀態碼和完整的實體內容。 showImg(https://segmentfault.com/img/bVbthNL?w=900&h=500); http報文 用于HTTP協議交互的信息被稱為HTTP報文。請求端的http報文叫做請求報文...

    Invoker 評論0 收藏0
  • java必知必會之SecureSocket

    SSL,Secure Sockets Layer,安全Socket層TLS,Transport Layer Security,傳輸層安全協議 package network.secure; import java.io.*; import javax.net.ssl.*; public class HTTPSClient { public static void main(Strin...

    kidsamong 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<