文章:https://nodejs.org/api/events.html#events_events
emitted:发射,启动函数。
Events:
如: 一个 net.Server
对象,每当一个客户连接到它,就发送一个事件; 当文件被打开时,一个 fs.ReadStream
发送一个事件; 当数据可读时,一个 stream 发送一个事件,这些有点像oracle 里面的语句触发器。
发送事件的所有对象时一个实例EventEmitter类
.这些对象提供了eventEmitter.on()
函数,允许一个或多个函数连接到对象发送的有名字的事件. 典型的, event names are camel-cased 字符串 but any valid JavaScript property key can be used.
当 EventEmitter
对象发送一个事件,所有连接到这个特定的事件的函数, 叫同步. 调用监听的任何返回值是忽视,然后被丢弃。
下面的例子显示一个简单的EventEmitter
实例,有一个单listener. The eventEmitter.on()
方法用于注册监听,而eventEmitter.emit()
方法用于 trigger the event,这里的事件无名字,怎么知道触发哪些事件,难道是ventEmitter 这个类的事件全触发?????
const EventEmitter = require('events');//EventEmitter类和事件events绑定在一起
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event');
Passing arguments and this
to listeners
The eventEmitter.emit()
方法允许任意设置多个参数传递给listener函数(也就是执行的函数). 注意,当一个普通的监听函数被EventEmitter调用时
,设置一个this,这个this是指EventEmitter对象,因为在函数里面有一个this值,是有调用函数时决定的,就是函数右边的对象,有就是对象,无,就是全局,还有就是node.js封装了,所以从外面传一个this当前对象过去.
const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
console.log(a, b, this);
// Prints:
// a b MyEmitter {
// domain: null,
// _events: { event: [Function] },
// _eventsCount: 1,
// _maxListeners: undefined }
});
myEmitter.emit('event', 'a', 'b');
使用ES6 Arrow Functions作为监听是可能的,然而, this
将不再指向EventEmitter
实例
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');
Asynchronous vs. Synchronous 异步 同步
TheEventListener
以他们注册的顺序,同步调用所有的listeners。
setImmediate()
or
process.nextTick()
方法,转到异步操作。
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
setImmediate(() => {
console.log('this happens asynchronously');
});
});
myEmitter.emit('event', 'a', 'b');
Handling events only once
当一个监听使用eventEmitter.on()方法注册时 , 每次named event ?被发送时,这个监听被调用。
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.on('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Prints: 2
使用eventEmitter.once()
方法, 多次调用监听,为特定的事件注册监听一次是可以的。一旦事件被发射,监听没有注册且被调用。
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.once('event', () => {
console.log(++m);
});
myEmitter.emit('event');//event监听注册且被调用
// Prints: 1
myEmitter.emit('event');//event监听没有注册且被调用
// Ignored
Error events #
在一个EventEmitter
实例里,当一个错误发生时, 典型的动作是一个'error'的事件
被启动emitted. 如果一个 'error'
事件被启动, 抛出错误,a stack trace is printed, and the Node.js process exits.
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// Throws and crashes Node.js
为了防止 Node.js process不崩溃, 在uncaughtException
事件上,注册了一个监听 。
const myEmitter = new MyEmitter();
process.on('uncaughtException', (err) => {
console.error('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Prints: whoops! there was an error
作为最佳实践,'error' 事件实际总是增加监听
const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
console.error('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Prints: whoops! there was an error
Class: EventEmitter#
The EventEmitter
class 被定义,由events
模板提供。
const EventEmitter = require('events');
当新监听是被增加时,All EventEmitters 启动事件'newListener'
,当新监听是被删除时,All EventEmitters 启动事件'removeListener'
Event: 'newListener'#
eventName
<any> The name of the event being listened forlistener
<Function> The event handler function
The EventEmitter
instance will emit its own 'newListener'
event before a listener is added to its internal array of listeners.
Listeners registered for the 'newListener'
event will be passed the event name and a reference to the listener being added.
The fact that the event is triggered before adding the listener has a subtle but important side effect: any additional listeners registered to the same name
within the 'newListener'
callback will be inserted before the listener that is in the process of being added.
const myEmitter = new MyEmitter();
// Only do this once so we don't loop forever
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Insert a new listener in front
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Prints:
// B
// A