【逐日一包0025】events

[github地点:https://github.com/ABCDdouyae…]

events

事宜触发器

大多数 Node.js 中心 API 构建于习用的异步事宜驱动架构,个中某些范例的对象(又称触发器,Emitter)会触发定名事宜来挪用函数(又称监听器,Listener)。一切能触发事宜的对象都是 EventEmitter 类的实例。 这些对象有一个 eventEmitter.on() 函数,用于将一个或多个函数绑定到定名事宜上。 事宜的定名通常是驼峰式的字符串。当 EventEmitter 对象触发一个事宜时,一切绑定在该事宜上的函数都会被同步地挪用

基础用法:实例化一个监听器,注册监听事宜‘event’,当经由过程emit触发‘event’时刻,会挪用回调函数

const EventEmitter = require('events');

class MyEmitter extends EventEmitter{}

const myEmitter = new MyEmitter();
myEmitter.on('event', ()=>{
    console.log('触发事宜')
});

myEmitter.emit('event');

eventEmitter.emit() 要领能够传恣意数目的参数到监听器函数。 当监听器函数被挪用时,this 关键词会被指向监听器所绑定的 EventEmitter 实例。

myEmitter.on('event1', function(a ,b){
    console.log(a, b, this)//1 2 MyEmitter{}
});

myEmitter.emit('event1', 1, 2);

也能够运用 ES6 的箭头函数作为监听器。但 this 关键词不会指向 EventEmitter 实例:

myEmitter.on('event', (a, b) => {
  console.log(a, b, this);
  // 打印: a b {}
});
myEmitter.emit('event', 'a', 'b');

运用 eventEmitter.once() 能够注册最多可挪用一次的监听器。 当事宜被触发时,监听器会被注销,然后再挪用。

let m = 0;
myEmitter.once('event', () => {
  console.log(++m);
});
myEmitter.emit('event');
// 打印: 1
myEmitter.emit('event');
// 不触发

当 EventEmitter 实例失足时,应当触发 ‘error’ 事宜。假如没有为 ‘error’ 事宜注册监听器,则当 ‘error’ 事宜触发时,会抛失足误、打印客栈跟踪、并退出 Node.js 历程

myEmitter.emit('error', new Error('毛病信息'));
// 抛失足误

作为最好实践,应当一直为 ‘error’ 事宜注册监听器。

myEmitter.on('error', (err) => {
  console.error('毛病信息');
});
myEmitter.emit('error', new Error('毛病信息'));
// 打印: 毛病信息

EventEmitter 类由 events 模块定义:

const EventEmitter = require('events');

当新增监听器时,会触发 ‘newListener’ 事宜;当移除已存在的监听器时,则触发 ‘removeListener’ 事宜。

newListener的参数分别为增添的监听事宜和该事宜的句柄函数

myEmitter.once('newListener', (event, listener)=>{
    console.log(event, listener)// 'event1' fn
});

function fn(){
    console.log(1)
}
myEmitter.on('event1', fn)

在增加监听器之前触发 ‘newListener’ 事宜有一个副作用: 假如在回调中注册同名事宜的监听器,则该监听器会被插进去到正被增加的监听器前面。

const myEmitter = new MyEmitter();
// 只处置惩罚一次,防止无穷轮回。
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // 在前面插进去一个新的监听器。
    myEmitter.on('event', () => {
      console.log('B');
    });
  }
});
myEmitter.on('event', () => {
  console.log('A');
});
myEmitter.emit('event');
// 打印:
//   B
//   A

removeListener的参数分别为移除的监听事宜和该事宜的句柄函数

EventEmitter.defaultMaxListeners默许情况下,每一个事宜能够注册最多 10 个监听器。 能够运用 emitter.setMaxListeners(n) 要领转变单个 EventEmitter 实例的限定。 能够运用 EventEmitter.defaultMaxListeners 属性转变一切 EventEmitter 实例的默许值。设置 EventEmitter.defaultMaxListeners 要郑重,由于会影响一切 EventEmitter 实例,包括之前建立的。 因此,优先运用 emitter.setMaxListeners(n) 而不是 `EventEmitter.defaultMaxListeners。限定不是硬性的。 EventEmitter 实例能够增加凌驾限定的监听器,但会向 stderr 输出跟踪正告,表明检测到能够的内存走漏。 关于单个 EventEmitter 实例,能够运用 emitter.getMaxListeners()emitter.setMaxListeners() 临时地消弭正告

console.log(myEmitter.getMaxListeners())//10
myEmitter.setMaxListeners(11);
function fn(){
    console.log(1)//11个1
}
for(var i=0;i<11;i++){
    myEmitter.on('event1', fn)
}

myEmitter.emit('event1')

emitter.addListener(eventName, listener), emitter.on(eventName, listener)的别号

emitter.emit(eventName[, …args])根据监听器注册的递次,同步地挪用每一个注册到名为 eventName 的事宜的监听器,并传入供应的参数。假如事宜有监听器,则返回 true,不然返回 false。

emitter.eventNames() 返回已注册监听器的事宜名数组。 数组中的值为字符串或 `Symbol。

const EventEmitter = require('events');
const myEE = new EventEmitter();
myEE.on('foo', () => {});
myEE.on('bar', () => {});

const sym = Symbol('symbol');
myEE.on(sym, () => {});

console.log(myEE.eventNames());
// 打印: [ 'foo', 'bar', Symbol(symbol) ]

emitter.getMaxListeners()返回 EventEmitter 当前的监听器最大限定数的值

emitter.listenerCount(eventName)返回正在监听的名为 eventName 的事宜的监听器的数目。

emitter.listeners(eventName)返回名为 eventName 的事宜的监听器数组的副本。

let fn1 = ()=>{}, fn2 = ()=>{};
myEmitter.on('foo', fn1);
myEmitter.on('foo', fn2);
console.log(myEmitter.listeners('foo'));
//[ [Function: fn1], [Function: fn2] ]

emitter.off(eventName, listener), emitter.removeListener() 的别号。

emitter.prependListener(eventName, listener)增加 listener 函数到名为 eventName 的事宜的监听器数组的开首。 不会搜检 listener 是不是已被增加。 屡次挪用并传入雷同的 eventName 和 listener 会致使 listener 被增加屡次。

emitter.prependOnceListener(eventName, listener)增加单次监听器 listener 到名为 eventName 的事宜的监听器数组的开首。 当 eventName 事宜下次触发时,监听器会先被移除,然后再挪用。

emitter.removeAllListeners([eventName])移除悉数监听器或指定的 eventName 事宜的监听器。

emitter.removeListener(eventName, listener)从名为 eventName 的事宜的监听器数组中移除指定的 listener。

let fn1 = ()=>{console.log(1)}, fn2 = ()=>{console.log(2)};//2
myEmitter.on('foo', fn1);
myEmitter.on('foo', fn2);
console.log(myEmitter.listeners('foo'));
//[ [Function: fn1], [Function: fn2] ]

myEmitter.off('foo', fn1);
myEmitter.emit('foo');

emitter.setMaxListeners(n)默许情况下,假如为特定事宜增加了凌驾 10 个监听器,则 EventEmitter 会打印一个正告。 这有助于发明内存泄漏。 然则,并非一切的事宜都要限定 10 个监听器。 emitter.setMaxListeners() 要领能够为指定的 EventEmitter 实例修正限定。 值设为 Infinity(或 0)示意不限定监听器的数目。

emitter.rawListeners(eventName)返回 eventName 事宜的监听器数组的拷贝,包括封装的监听器(比方由 .once() 建立的)。

const emitter = new EventEmitter();
emitter.once('log', () => console.log('只纪录一次'));

// 返回一个数组,包括了一个封装了 `listener` 要领的监听器。
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];

// 打印 “只纪录一次”,但不会解绑 `once` 事宜。
logFnWrapper.listener();

// 打印 “只纪录一次”,且移除监听器。
logFnWrapper();

emitter.on('log', () => console.log('延续地纪录'));
// 返回一个数组,只包括 `.on()` 绑定的监听器。
const newListeners = emitter.rawListeners('log');

// 打印两次 “延续地纪录”。
newListeners[0]();
emitter.emit('log');
    原文作者:王炜
    原文地址: https://segmentfault.com/a/1190000017313475
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞