EventEmitter

# EventEmitter Stability: 2 - Stable ## EventEmitter.defaultMaxListeners 每个事件默认可以注册最多 10 个监听器。 单个 EventEmitter 实例的限制可以使用 emitter.setMaxListeners(n) 方法改变。 所有 EventEmitter 实例的默认值可以使用 EventEmitter.defaultMaxListeners 属性改变。 设置 EventEmitter.defaultMaxListeners 要谨慎,因为会影响所有 EventEmitter 实例,包括之前创建的。 因而,调用 emitter.setMaxListeners(n) 优先于 EventEmitter.defaultMaxListeners。 注意,与Node.js不同,这是一个**硬性限制**。 EventEmitter 实例不允许添加更多的监听器,监听器超过最大数量时会抛出TooManyListenersException。 ```js emitter.setMaxListeners(emitter.getMaxListeners() + 1); emitter.once('event', () => { // 做些操作 emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); }); ``` ## EventEmitter.addListener(eventName, listener) - eventName {any} - listener {Function} emitter.on(eventName, listener) 的别名。 ## EventEmitter.emit(eventName[, ...args]) - eventName {any} - args {any} 按监听器的注册顺序,同步地调用每个注册到名为 eventName 事件的监听器,并传入提供的参数。 如果事件有监听器,则返回 true ,否则返回 false。 ## EventEmitter.eventNames() 返回一个列出触发器已注册监听器的事件的数组。 数组中的值为字符串或符号。 ```js const myEE = events.emitter(); myEE.on('foo', () => {}); myEE.on('bar', () => {}); const sym = Symbol('symbol'); myEE.on(sym, () => {}); console.log(myEE.eventNames()); // 打印: [ 'foo', 'bar', Symbol(symbol) ] ``` ## EventEmitter.getMaxListeners() 返回 EventEmitter 当前的最大监听器限制值,该值可以通过 emitter.setMaxListeners(n) 设置或默认为 EventEmitter.defaultMaxListeners。 ## EventEmitter.listenerCount(eventName) eventName {string} 正在被监听的事件名 返回正在监听名为 eventName 的事件的监听器的数量。 ## EventEmitter.listeners(eventName) - eventName {string} 返回名为 eventName 的事件的监听器数组的副本。 ```js server.on('connection', (stream) => { console.log('someone connected!'); }); console.log(util.inspect(server.listeners('connection'))); // 打印: [ [Function] ] ``` ## EventEmitter.on(eventName, listener) - eventName {any} 事件名 - listener {Function} 回调函数 添加 listener 函数到名为 eventName 的事件的监听器数组的末尾。 不会检查 listener 是否已被添加。 多次调用并传入相同的 eventName 和 listener 会导致 listener 被添加与调用多次。 ```js server.on('connection', (stream) => { console.log('有连接!'); }); ``` 返回一个 EventEmitter 引用,**可以链式调用**。 默认情况下,事件监听器会按照添加的顺序依次调用。 emitter.prependListener() 方法可用于将事件监听器添加到监听器数组的开头。 ```js const myEE = events.emitter(); myEE.on('foo', () => console.log('a')); myEE.prependListener('foo', () => console.log('b')); myEE.emit('foo'); // 打印: // b // a ``` ## EventEmitter.once(eventName, listener) - eventName {any} 事件名 - listener {Function} 回调函数 添加一个单次 listener 函数到名为 eventName 的事件。 下次触发 eventName 事件时,监听器会被移除,然后调用。 ```js server.once('connection', (stream) => { console.log('首次调用!'); }); ``` 返回一个 EventEmitter 引用,可以链式调用。 默认情况下,事件监听器会按照添加的顺序依次调用。 emitter.prependOnceListener() 方法可用于将事件监听器添加到监听器数组的开头。 ```js const myEE = events.emitter(); myEE.once('foo', () => console.log('a')); myEE.prependOnceListener('foo', () => console.log('b')); myEE.emit('foo'); // 打印: // b // a ``` ## EventEmitter.prependListener(eventName, listener) - eventName {any} 事件名 - listener {Function} 回调函数 添加 listener 函数到名为 eventName 的事件的监听器数组的开头。 不会检查 listener 是否已被添加。 多次调用并传入相同的 eventName 和 listener 会导致 listener 被添加与调用多次。 ```js server.prependListener('connection', (stream) => { console.log('有连接!'); }); ``` 返回一个 EventEmitter 引用,可以链式调用。 ## EventEmitter.prependOnceListener(eventName, listener) - eventName {any} 事件名 - listener {Function} 回调函数 添加一个单次 listener 函数到名为 eventName 的事件的监听器数组的开头。 下次触发 eventName 事件时,监听器会被移除,然后调用。 ```js server.prependOnceListener('connection', (stream) => { console.log('首次调用!'); }); ``` 返回一个 EventEmitter 引用,可以链式调用。 ## EventEmitter.removeAllListeners([eventName]) - eventName {any} 移除全部或指定 eventName 的监听器。 注意,在代码中移除其他地方添加的监听器是一个不好的做法,尤其是当 EventEmitter 实例是其他组件或模块创建的。 返回一个 EventEmitter 引用,可以链式调用。 ## EventEmitter.removeListener(eventName, listener) - eventName {any} - listener {Function} 从名为 eventName 的事件的监听器数组中移除指定的 listener。 ```js const callback = (stream) => { console.log('有连接!'); }; server.on('connection', callback); // ... ``` ## server.removeListener('connection', callback); removeListener 最多只会从监听器数组里移除一个监听器实例。 如果任何单一的监听器被多次添加到指定 eventName 的监听器数组中,则必须多次调用 removeListener 才能移除每个实例。 注意,一旦一个事件被触发,所有绑定到它的监听器都会按顺序依次触发。 这意味着,在事件触发后、最后一个监听器完成执行前,任何 removeListener() 或 removeAllListeners() 调用都不会从 emit() 中移除它们。 随后的事件会像预期的那样发生。 ```js const myEmitter = events.emitter(); const callbackA = () => { console.log('A'); myEmitter.removeListener('event', callbackB); }; const callbackB = () => { console.log('B'); }; myEmitter.on('event', callbackA); myEmitter.on('event', callbackB); // callbackA 移除了监听器 callbackB,但它依然会被调用。 // 触发是内部的监听器数组为 [callbackA, callbackB] myEmitter.emit('event'); // 打印: // A // B // callbackB 被移除了。 // 内部监听器数组为 [callbackA] myEmitter.emit('event'); // 打印: // A ``` 因为监听器是使用内部数组进行管理的,所以调用它会改变在监听器被移除后注册的任何监听器的位置索引。 虽然这不会影响监听器的调用顺序,但意味着由 emitter.listeners() 方法返回的监听器数组副本需要被重新创建。 返回一个 EventEmitter 引用,可以链式调用。 ## EventEmitter.setMaxListeners(n) - n {number} 默认情况下,如果为特定事件添加了超过 10 个监听器,则 EventEmitter 会打印一个警告。 此限制有助于寻找内存泄露。 但是,并不是所有的事件都要被限为 10 个。 emitter.setMaxListeners() 方法允许修改指定的 EventEmitter 实例的限制。 值设为 Infinity(或 0)表明不限制监听器的数量。 返回一个 EventEmitter 引用,可以链式调用。 # events.broadcast: 脚本间广播 脚本间通信除了使用engines模块提供的ScriptEngine.emit()方法以外,也可以使用events模块提供的broadcast广播。 events.broadcast本身是一个EventEmitter,但它的事件是在脚本间共享的,所有脚本都能发送和监听这些事件; 事件处理会在脚本主线程执行(后续可能加入函数onThisThread(eventName, ...args)来提供在其他线程执行的能力)。 例如在一个脚本发送一个广播hello: ```js events.broadcast.emit("hello", "小明"); ``` 在其他脚本中监听并处理: ```js events.broadcast.on("hello", function(name){ toast("你好, " + name); }); //保持脚本运行 setInterval(()=>{}, 1000); ```