创建特定的循环行为

时间:2015-06-28 04:52:23

标签: javascript event-handling iteration eventemitter

为我的项目创建内部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的本机实现如何处理这个?

1 个答案:

答案 0 :(得分:0)

自己查看节点源后,我找到了their solution in events.js

listeners = handler.slice();

基本上,它会使侦听器数组的副本进行迭代,以便在侦听器从原始数组中删除自身时,副本的indeces不受影响。