亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

NodeJS Events 必知必會

bladefury / 2926人閱讀

摘要:超過會有警告輸出。實例默認(rèn)的某個事件最大監(jiān)聽者的數(shù)量,默認(rèn)是。事件監(jiān)聽數(shù)量是檢測內(nèi)存泄露的一個標(biāo)準(zhǔn)一個維度。例如同一個實例類型事件個監(jiān)聽者,類型事件個監(jiān)聽者,這個并不會有告警。

1. 環(huán)境

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()方法可以傳不限制數(shù)量的參數(shù)。

除了箭頭函數(shù)外,在回調(diào)函數(shù)內(nèi)部,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. 同步還是異步調(diào)用listeners?

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

// 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

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

同步去調(diào)用事件監(jiān)聽者,能夠確保按照注冊順序去調(diào)用事件監(jiān)聽者,并且避免競態(tài)條件和邏輯錯誤。

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. 不訂閱,就發(fā)飆的錯誤事件

error是一個特別的事件名,當(dāng)這個事件被觸發(fā)時,如果沒有對應(yīng)的事件監(jiān)聽者,則會導(dǎo)致程序崩潰。

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的監(jiān)聽器

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. 內(nèi)部事件 newListener與removeListener

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

newListener在訂閱者被加入到訂閱列表前觸發(fā)

removeListener在訂閱者被移除訂閱列表后觸發(fā)

// 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)
})

輸出:

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

----
myEmitter
[Function]
8. 事件監(jiān)聽數(shù)量限制

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

EventEmitter.defaultMaxListeners: EventEmitter類默認(rèn)的最大監(jiān)聽者的數(shù)量,默認(rèn)是10。超過會有警告輸出。

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

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

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

改變EventEmitter的最大監(jiān)聽數(shù)量會影響到所有EventEmitter實例

該變EventEmitter實例的最大監(jiān)聽數(shù)量只會影響到實例自身

如無必要,最好的不要去改變默認(rèn)的監(jiān)聽數(shù)量限制。事件監(jiān)聽數(shù)量是node檢測內(nèi)存泄露的一個標(biāo)準(zhǔn)一個維度。

EventEmitter實例的最大監(jiān)聽數(shù)量不是一個實例的所有監(jiān)聽數(shù)量。

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

如果在事件中發(fā)現(xiàn)類似的告警提示Possible EventEmitter memory leak detected,要知道從事件最大監(jiān)聽數(shù)的角度去排查問題。

// 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

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/97169.html

相關(guān)文章

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

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

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

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

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

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

    kidsamong 評論0 收藏0

發(fā)表評論

0條評論

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