在nodejs / events.js的emitMany函数中克隆侦听器数组的原因是什么?

时间:2016-04-13 10:44:12

标签: javascript node.js eventemitter

功能代码(source code on github):

function emitMany(handler, isFn, self, args) {
  if (isFn)
    handler.apply(self, args);
  else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      listeners[i].apply(self, args);
  }
}

在这一行:

var listeners = arrayClone(handler, len);

克隆一个侦听器数组(在此作用域中命名为handler),然后将其克隆分配给名为listeners的新变量。我想知道这有什么用。

我怀疑这是因为侦听器可以从列表中删除自己,并且该操作会破坏for循环中的计数器(删除后列表项的索引会发生变化,但计数器i会盲目地保留不知道那个)。

我的解释是否正确,或者可能还有其他/更多内容?

2 个答案:

答案 0 :(得分:1)

此行为一般用于emit()(不仅仅是内部emitAny()),并且至少可以防止事件处理程序将自身添加为同一事件的事件处理程序(或类似情况) )这可能会导致单个emit()的无限循环。例如:

emitter.on('foo', function fooHandler() {
  emitter.on('foo', fooHandler);
});

答案 1 :(得分:1)

那是因为当发出相应的事件时,处理程序可能会为该事件添加/删除处理程序,从而修改迭代的数组。

foo.on('bar', function() {
  foo.on('bar', function() { // should not be invoked now / but for the next and subsequent events
  })
})

第一次触发'bar'事件时不应调用第二个处理程序,因此必须在执行处理程序之前克隆处理程序数组。