创建特定的循环行为
Creating particular loop behavior
在为我的项目创建内部 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
是一个对象,每个键都是一个事件名称,每个值都是要为相应事件调用的事件处理程序数组。
然而,正如我在 中观察到的那样,对于附加在 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
的本机实现如何处理这个问题?
自己查看节点源后发现their solution in events.js:
listeners = handler.slice();
基本上,它会制作一个要迭代的侦听器数组的副本,这样如果侦听器从原始数组中删除自己,副本的索引不受影响。
在为我的项目创建内部 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
是一个对象,每个键都是一个事件名称,每个值都是要为相应事件调用的事件处理程序数组。
然而,正如我在 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
的本机实现如何处理这个问题?
自己查看节点源后发现their solution in events.js:
listeners = handler.slice();
基本上,它会制作一个要迭代的侦听器数组的副本,这样如果侦听器从原始数组中删除自己,副本的索引不受影响。