无法删除动态事件侦听器

Cannot remove dynamic event listeners

当使用常规函数绑定到事件时,我可以毫无问题地删除它。但是当使用上下文函数的动态列表时,我无法删除那些监听器。

这是整个测试应用程序的简化版本:

'use strict';

var util = require('util');
var EventEmitter = require('events').EventEmitter;

function CustomEventEmitter() {
    EventEmitter.call(this);
}

util.inherits(CustomEventEmitter, EventEmitter);

var obj = new CustomEventEmitter();

var onError, exists = false;

for (var i = 0; i < 20; i++) {

    onError = function (err) {
        console.log(err, i);
    };

    if (exists) {
        obj.removeListener('error', onError);
        exists = false;
    }

    obj.on('error', onError);
    exists = true;
}

它将导致:

Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit

因为调用 removeListener 并没有真正删除侦听器。

应该如何删除这样的动态侦听器?

是啊!当你做

var onError = function (err) {
    console.log(err, i);
};

将新函数分配给 onError 变量。由于您在 obj.on('error', onError);obj.removeListener('error', onError); 之间执行此操作,因此您尝试删除的那个与您添加的不一样。所以什么都没有被删除。

如果你这样做:

'use strict';

var util = require('util');
var EventEmitter = require('events').EventEmitter;

function CustomEventEmitter() {
    EventEmitter.call(this);
}

util.inherits(CustomEventEmitter, EventEmitter);

var obj = new CustomEventEmitter();

var exists = false;
var onError;

for (var i = 0; i < 20; i++) {
    if (exists) {
        obj.removeListener('error', onError);
        exists = false;
    }

    onError = function (err) {
        console.log(err, i);
    };

    obj.on('error', onError);
    exists = true;
}

它会做你想做的事。