Node.jsのEvent Emitter

20818 ワード

ほとんどのNode.jsコアAPIは、いくつかのタイプのオブジェクト(触発器、Emitter)が、関数(またはモニタ、Listener)を呼び出すためにネーミングイベントをトリガします.例えば、net.Serverは、新しい接続があるたびにイベントをトリガし、fs.ReadStreamはファイルを開いたときにイベントをトリガし、streamはデータ読み取り時にイベントをトリガする.
公式サイト上のこの話から得られる情報は、Node.jsの核心APIは共通の非同期イベント駆動を使用しているので、これは必ず独自のカテゴリーになります.今日は私たちは一緒にこのクラスを勉強します.EventEmitterイベントをトリガできるすべてのオブジェクトは、EventEmitterクラスの例です.これらのオブジェクトは、一つ以上の関数を名前付きイベントに結びつけるためのeventEmitter.on関数があります.イベントの名前は通常、ラクダのピーク式の文字列ですが、有効なJavaScript属性キーは何でも使用できます.
まず簡単な例を紹介します.
const {
      EventEmitter } = require('events')
const eventEmitter = new EventEmitter()

//       
eventEmitter.on('say', () => {
     
  console.log('say hello');
})

setTimeout(() => {
     
  eventEmitter.emit('say')
}, 1000)
console.log('    !');

//     
//     !
// say hello
上記の方法を観察することによって、
  • は、EventEmitterを介してイベントを登録し、onに等しい.
  • は、傍受されたイベントを非同期的にトリガすることができる.
  • また見ます
    const {
          EventEmitter } = require('events')
    const eventEmitter = new EventEmitter()
    
    eventEmitter.on('listener1', (argv1, argv2) => {
         
      console.log('listener1', argv1, argv2);
    })
    eventEmitter.on('listener1', (argv1, argv2) => {
         
      console.log('listener2', argv1, argv2);
    })
    eventEmitter.on('listener1', (argv1, argv2) => {
         
      console.log('listener3', argv1, argv2);
      return 'xx' //      
    })
    // prependListener    listener       eventName             。
    eventEmitter.prependListener('listener1', (argv1, argv2) => {
         
      console.log('prependListener', argv1, argv2);
    })
    
    setTimeout(() => {
         
      eventEmitter.emit('listener1', 'argv1', 'argv2')
    }, 1000)
    console.log('    !');
    
    //     
    //     !
    // prependListener argv1 argv2
    // listener1 argv1 argv2
    // listener2 argv1 argv2
    // listener3 argv1 argv2
    
    上記の例から、
  • 同じ傍受イベントで、複数の傍受が可能です.
  • 同じイベントで、モニターを追加すると、主に実行順序に反映されるモニター配列が統制されている.
  • によって呼び出されたモニタから返ってくる値は無視されて破棄されます.
  • また見ます
    const {
          EventEmitter } = require('events')
    const eventEmitter = new EventEmitter()
    
    eventEmitter.on('say', () => {
         
        console.log(111);
      })
      .on('say', () => {
         
        console.log(222);
      })
    
    setTimeout(() => {
         
      eventEmitter.emit('say')
    }, 1000)
    console.log('    !');
    
    //     !
    // 111
    // 222
    
    上記の例から、
  • は、リンク式呼び出しが可能なようにEventEmitterへの参照を返します.
  • これから見ます
    const {
          EventEmitter } = require('events')
    const eventEmitter = new EventEmitter()
    
    // setMaxListeners            
    eventEmitter.setMaxListeners(3)
      .on('say', () => {
         
        console.log(111);
      })
      .on('say', () => {
         
        console.log(222);
      })
      .on('say', () => {
         
        console.log(333);
      })
      .on('say', () => {
         
        console.log(444);
      })
    
    //              
    console.log(eventEmitter.listenerCount('say'))
    
    setTimeout(() => {
         
      eventEmitter.emit('say')
    }, 1000)
    console.log('    !');
    
    // 4
    //     !
    // (node:7748) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 4 say listeners added. Use emitter.setMaxListeners() to increase limit
    // 111
    // 222
    // 333
    // 444
    
    上記の例から、
  • 特定のイベントに設定されたモニターの数を超過した場合、EventEmitterは警告を印刷します.これはメモリリークの発見に役立つ.
  • listenerCount(「listenerName」)は、特定のイベントのモニター接続数
  • を取得する.
    最後に見る
    const {
          EventEmitter } = require('events')
    const eventEmitter = new EventEmitter()
    
    eventEmitter.emit('error')
    // events.js:189
    //     throw err; // Unhandled 'error' event
    //     ^
    
    // Error [ERR_UNHANDLED_ERROR]: Unhandled error. (undefined)
    //     at EventEmitter.emit (events.js:187:17)
    //     at Object. (C:\Users\admin\Desktop\blogs
    ode\demo.js:71:14)
    // at Module._compile (internal/modules/cjs/loader.js:778:30) // at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10) // at Module.load (internal/modules/cjs/loader.js:653:32) // at tryModuleLoad (internal/modules/cjs/loader.js:593:12) // at Function.Module._load (internal/modules/cjs/loader.js:585:3) // at Function.Module.runMain (internal/modules/cjs/loader.js:831:12) // at startup (internal/bootstrap/node.js:283:19) // at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
    まとめ:
  • EventEmitterは特別なイベントerrorを定義しています.これは間違った意味を含んでいます.私たちは異常に遭遇した時、常にerrorイベントをトリガします.errorがトリガされると、EventEmitterは応答していないモニターをNode.jsが異常としてプログラムを終了し、エラー情報を出力すると規定しています.
  • ですので、addListener(event, listener)
  • を先に定義したほうがいいです.eventEmitter.on('error', callback)の一般的な方法
  • EventEmitter:イベントを指定するために単一のモニターを登録します.つまり、モニターは最大一回しかトリガされません.トリガが発生したらすぐにモニターを解除します.
  • once(event, listener):指定されたイベントのいずれかを削除するモニターは、イベントが登録されたモニターでなければならない.二つのパラメータを受け入れます.一つ目はイベント名で、二つ目はコールバック関数名です.
  • removeListener(event, listener):すべてのイベントのすべてのモニターを削除し、イベントを指定すると、指定されたイベントのすべてのモニターを削除する.
  • removeAllListeners([event]):指定されたイベントのモニタ配列を返します.