stream.Readable.prototype.on如何处理node.js源代码中的事件?

时间:2018-02-27 04:06:45

标签: javascript node.js

stream.Readable中阅读Node.js的代码时,我感到很困惑。

这是源代码:

https://github.com/nodejs/node/blob/master/lib/_stream_readable.js#L778-L799

Readable.prototype.on = function(ev, fn) {
  const res = Stream.prototype.on.call(this, ev, fn);

  if (ev === 'data') {
    // Start flowing on next tick if stream isn't explicitly paused
    if (this._readableState.flowing !== false)
      this.resume();
  } else if (ev === 'readable') {
    const state = this._readableState;
    if (!state.endEmitted && !state.readableListening) {
      state.readableListening = state.needReadable = true;
      state.emittedReadable = false;
      if (!state.reading) {
        process.nextTick(nReadingNextTick, this);
      } else if (state.length) {
        emitReadable(this);
      }
    }
  }

  return res;
};

显然,if语句只处理dataReadable事件,但根据API documenton方法stream.readable还接受其他活动,例如closeenderror

所以我的问题是:

根据源代码,stream.Readable如何处理除datareadable以外的其他事件?

1 个答案:

答案 0 :(得分:1)

您在这里看到的是.on()方法的覆盖,以便Readable类可以查看正在连接的事件侦听器,并且可以在有人为{{安装侦听器时执行某些特殊操作1}}事件或data事件。

此功能的第一行:

readable

是Readable将回调和事件名称参数传递给其父级的位置,以便运行正常的实现。 const res = Stream.prototype.on.call(this, ev, fn); 实现了Stream接口,因此使用EventEmitter调用超级方法会给Stream.prototype.on.call(this, ev, fn)预期的默认行为。

然后在调用父节点之后,它会检查某人正在侦听的事件是.on()事件还是data事件,然后在其中一个事件侦听器执行时实现一些额外的功能附接。

对于readable事件,它会恢复流,以便它在暂停时开始流动并且如果设置为流动模式。这可能是因为最初创建和配置data时,如果它在附加Readable事件侦听器之前开始流式传输流,则可能会错过流上的数据。因此,在有人聆听data事件之前,它才会开始流动。

请注意,流上可能会发生大量过度事件,并且这些事件都是通过第一行中对基类的调用来处理的。您在这里看到的只是data类在首次添加两个特定事件侦听器时要实现的一些特殊行为。此代码不会影响何时发送这些事件或如何侦听它们。当首次附加其中一个事件的侦听器时,它只会触发Readable状态中的一些小行为。