为我的项目创建内部EventEmitter
时,我很好奇如何为附加的事件处理程序生成特定的循环迭代行为。这是对我的关注的证明:
MyEventEmitter.prototype.emit = function (name, event) {
var index;
if (name in this.events) {
for (index = 0; index < this.events[name].length; index++) {
this.events[name][index].call(this, event);
}
}
};
为了澄清,this.events
是一个对象,每个键都是一个事件名称,每个值都是要为相应事件调用的事件处理程序数组。
但是,正如我在Unexpected behavior of Array.prototype.splice中观察到的那样,对于附加MyEventEmitter.prototype.once
的事件处理程序,这会失败,因为包装器事件处理函数会自行删除,导致迭代跳过事件处理程序的内容。紧接在数组中的一次性事件处理程序之后的数组。这就是我的意思:
var array = [1, 2, 3, 4, 5], index;
for (index = 0; index < array.length; index++) {
// log event handlers that get called
console.log(array[index]);
// let's assume that `3` is like an event handler that removes itself
if (array[index] === 3) {
array.splice(index, 1);
}
}
这将记录以下内容:
1
2
3
5
请注意4
不会被迭代,因为3
会自行删除。我如何写emit
来容纳这个?或者,如果合适,EventEmitter
的本机实现如何处理这个?
答案 0 :(得分:0)
自己查看节点源后,我找到了their solution in events.js:
listeners = handler.slice();
基本上,它会使侦听器数组的副本进行迭代,以便在侦听器从原始数组中删除自身时,副本的indeces不受影响。