Node.js Events

文章:https://nodejs.org/api/events.html#events_events

emitted:发射,启动函数。

Events:

  java中线程有两种方式:1、大家一窝蜂去竞争同一资源,但是一旦有人抢到资源一直占用
                                         2、合作方式,你干完活了,通知我。
                    上面两种方式,都是独占资源的方式,两个都叫同步。

例如: 打电话告诉家人,我钱快用完了,寄点钱来,
      在java中,哪么家里人马上处理寄钱这件事,如果钱不够,就挂起,去弄钱,弄完之后,寄钱,这件事结束
           异步:家里人接到电话后,回答,知道了,去干别的事,过几天,工资发了,才开始正式寄钱。
   但是,对于多人用同一洗澡间,即竞争同一资源的情况下,哪么异步是怎么实现的呢?上面觉得是不太急的事,可以用异步???                           大多数建立的Node.js核心API,通常是用异步事件驱动的体系结构, 在这种体系结构中,某种对象 (也叫"发射器") 定期的发送一些named 事件,这将导致函数对象 ("监听") 被调用

如: 一个 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 异步 同步

The  EventListener  以他们注册的顺序,同步调用所有的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 for
  • listener <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





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值