node.js - 删除当前发出事件的事件监听器

标签 node.js events stream

我有以下示例应用程序,用 Node.js 编写:

'use strict';

var events = require('events'),
    util = require('util');

var EventEmitter = events.EventEmitter;

var Foo = function () {};

util.inherits(Foo, EventEmitter);

var foo = new Foo();

foo.once('x', function () {
  foo.removeAllListeners();
  console.log('Google!');
});

foo.once('x', function () {
  foo.removeAllListeners();
  console.log('Yahoo!');
});

foo.emit('x');

它打印:

Google!
Yahoo!

现在我的问题是:显然 removeAllListeners 不会影响当前绑定(bind)到该事件的事件监听器。这是随机的,还是故意的? (我使用 0.10.32 和 0.11.13 检查了这一点)

我的问题的背景是:如果我将两个事件处理程序绑定(bind)到流的 end 事件,并且其中一个调用 removeAllListeners,Node.js 是否能保证两者总是会被运行,还是这只是运气好?

最佳答案

在查看 .emit() 方法的实现时,看起来一旦它开始处理事件并调用监听器,该事件就不会受到任何调用 的代码的影响removeAllListeners() 因此在您的示例中,两个监听器都会被调用。

.emit() 的代码在执行任何监听器之前都会复制监听器数组,以便一旦开始执行一个监听器,它将执行所有监听器,即使它们已被删除执行期间。这是相关的代码:

  } else if (util.isObject(handler)) {
    len = arguments.length;
    args = new Array(len - 1);
    for (i = 1; i < len; i++)
      args[i - 1] = arguments[i];

    listeners = handler.slice();
    len = listeners.length;
    for (i = 0; i < len; i++)
      listeners[i].apply(this, args);
  }

来自此处的 EventEmitter 实现:https://github.com/joyent/node/blob/857975d5e7e0d7bf38577db0478d9e5ede79922e/lib/events.js#L120

在这段代码中,handler 将是一个监听器函数数组。线路

listeners = handler.slice()

在执行任何监听器之前创建监听器数组的副本。这是可以预料的,因为如果允许代码在迭代时自由修改正在迭代的数组,则该数组的迭代可能会困惑(重复或跳过)。因此,它会在调用任何监听器之前卡住要调用的监听器集。

关于node.js - 删除当前发出事件的事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26634943/

相关文章:

node.js - 托管 Cloud9 IDE 的 Facebook URL 问题

events - 在运行时获取文本框 dojo 小部件内的值

c# - 对象没有得到垃圾收集

android-streaming mp3 文件到其他设备

javascript - 使用 node-http-proxy 转发每个请求

javascript - canvas.toDataURL() 不是函数 - 错误 node-webGL 包装器

javascript - 使用 anchor 到达页面时触发事件

linux - 附加到正在运行的进程的输出

python - 让字符串充当文件

eclipse - 如何在 nodeclipse 上进行交互式调试