【问题标题】:Creating particular loop behavior创建特定的循环行为
【发布时间】:2015-09-14 18:28:49
【问题描述】:

在为我的项目创建内部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 来适应这个?或者,如果合适的话,EventEmitters 的原生实现如何处理这个问题?

【问题讨论】:

  • @jooko 谢谢,忘记添加标签

标签: javascript event-handling iteration eventemitter


【解决方案1】:

自己查看了节点源码后发现their solution in events.js

listeners = handler.slice();

基本上,它会创建一个监听器数组的副本以进行迭代,这样如果监听器从原始数组中删除自己,副本的索引不受影响。

【讨论】:

    猜你喜欢
    • 2018-08-23
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 2015-06-06
    • 1970-01-01
    • 2018-10-17
    相关资源
    最近更新 更多