在事件发射器中调用.emit()之前的.on()是否存在时序问题?

时间:2014-09-29 02:47:17

标签: node.js events eventemitter

使用此代码,其中f是一个具有事件“body”的流,它使用m调用侦听器 - 这本身就是一个发出事件的流:

f.on('message', function(m) {
  m.on('body', function(stream, info) {
    var b = '';
    stream.on('data', function(d) {
      b += d;
    });
    stream.on('end', function() {
      if (/^header/i.test(info.which))
        msg.header = Imap.parseHeader(b);
      else
        msg.body = b;
    });
  });
  m.on('attributes', function(attrs) {
    msg.attrs = attrs;
    msg.contentType = partID[1];
  });
});
f.on('end', function() {
  if (hadErr)
    return;
  cb(undefined, msg);
});

后端发出'message'事件,并传递m个对象。然后,代码会侦听事件bodyattributes。除了我的小脑有点危机(我不习惯处理流)之外,这一切都很简单。特别是:后端如何从fm对象发出,以保证在正确的时间确实调用事件?

具体做法是:

  • 一般而言,f如何编码,以确保m m在m.on('body', function(stream, info) {被调用之前不会发出?
  • 是否需要在发出事件之前使用on()添加侦听器才能捕获它?
  • 如果是,那是否意味着fm会在此处注册的代码之后发出事件?
  • 如果后端应该保证在 m.emit('end')之后b.emit('end')被称为,那么这怎么可能真的发生,仍然保证{{1被称为on()的任何一个事件都会被发出?

好的,我对此事100%感到困惑。我显然缺少一些基本和关键的东西,因此我甚至无法提出正确的问题......! (道歉)

1 个答案:

答案 0 :(得分:3)

  

是否需要在发出事件之前使用on()添加侦听器才能捕获它?

  

如果是这样,这是否意味着f和m将在此处的代码注册后发出事件?

不,事件不在任何地方排队。如果没有人在听他们,他们就会迷失。我认为,无论如何,这都是你要求的...... fm似乎不会在您的代码中发出事件。

  

如果后端应该保证在m.emit(' end')之后调用b.emit(' end'),那怎么可能真的发生,仍然保证在发出任何一个事件之前调用on()?

b是您示例中的字符串?我不确定你在这里问的是什么。

以不同的方式思考。调用.on时,函数将订阅消息通道。这些消息在订阅该函数之前已经流动,并且如果该函数被取消订阅将继续流动。 .on.removeListener()只设置特定功能的订阅状态。

即使没有任何内容正在侦听,也可以发出事件。事件可以随时发生,如果没有什么是聆听,他们就不会去任何地方。 (对此的一个例外是Node.js中内置的错误事件,如果没有错误处理程序,则会将其转换为实例异常。)

  

一般来说,为了确保mm不会发射到m.on(' body',function(stream,info){叫?

我仍然没有特别关注您所要求的内容,因为您展示的代码都没有发出任何内容。但是,你真的不想这样做。您需要在打开流之前设置事件处理程序,或者执行任何导致事件被触发的操作。

您可能会对新对象的事件处理顺序感到困惑。在Node.js中,有一条规则......永远不要直接从构造函数中发出。始终使用nextTick()或类似内容。这样,在实例化之后,任何将自身附加到事件处理程序的代码都可以在发出事件之前这样做。

此外,如果您正在使用流,请考虑使用readable事件,以便在您准备好从中读取数据流之前保持暂停状态。拉动与推动。