删除处理程序本身的事件处理程序

时间:2017-10-04 11:29:14

标签: javascript node.js function event-handling

简而言之:我想将.bind的结果绑定在其自己的电话中

var bound = foo.bind(this,bound);

因为我不确定如何解决我的问题。

问题:

我有一个依赖于其他项目数组的项目。 删除其中一个项后,我想删除依赖项并删除依赖项上的所有侦听器

我正在努力删除其他依赖项的事件处理程序。我试图使用bind,但由于处理函数是删除侦听器的函数,我发现我必须将bind()调用的结果绑定在它自己的调用中一个论点。这样做不起作用。

绑定调用bellow绑定未处理版本的'处理程序'作为参数,因此removeEventListener不起作用,因为它是函数的不同副本。

问题是:我可以使用bind来执行此操作和/或我该如何解决此问题?

我正在使用eventemitter3,但任何事件库都应该相同。

setHandlers(dependentItem,dependencies)
{
    var handler = this.onDependencyRemoved;
    handler = handler.bind(this,dependentItem,dependencies,handler);//bind itself as third argument
    dependencies.forEach(dependency => {
        dependency.addEventListener("removed",handler);
    });
}
onDependencyRemoved(dependentItem,dependencies,handler)
{
     dependentItem.remove();
     dependencies.forEach(dependency => {
          dependency.removeEventListener("removed",handler);
     });
}

修改

完成在nodejs中运行的工作示例:

const EventEmitter = require('events');
//const EventEmitter = require('eventemitter3');

class MyEmitter extends EventEmitter {
    remove() {
        console.log("I'm being removed, this should happen only once");
    }
}
var dependent = new MyEmitter();
var dependencies = [new MyEmitter(),new MyEmitter()];

var handler = (e) => removeHandler(dependencies,dependent,handler);

dependencies.forEach(dependency => dependency.once('removed',handler));

var removeHandler = function(dependencies,dependent,handler) {
    //remove the dependent object because one of the dependencies was removed
    dependent.remove();
    //remove the listeners from all of the dependencies
    dependencies.forEach(dependency => {
        console.log('before removing: '+dependency.listeners('removed').length);
        dependency.removeListener('removed',handler);
        console.log('after removing: '+dependency.listeners('removed').length);
    });
}

//should remove the dependent object
dependencies[0].emit("removed");
//should not do anything anymore since the listeners are removed
dependencies[1].emit("removed");

2 个答案:

答案 0 :(得分:7)

你不能使用bind来做到这一点,但是你可以通过使用一个闭包来做到这一点 - 直接用于绑定函数,或者你自己的辅助函数类似于bind。它就像

一样简单
const handler = (e) => this.onDependencyRemoved(dependentItem, dependencies, handler, e);

我不确定为什么这两个函数都是任何方法;他们看起来很静止。 可能使它们成为dependentItem的方法是有意义的,在这种情况下,参数甚至整个handler都不需要存储在闭包变量中,但可以在构造函数中初始化实例属性。

答案 1 :(得分:6)

有更好的方法来解决其他人提到的问题。但是,代码存在一个更基本的问题:

var bound = foo.bind(this,bound);

执行时代码中bound的值为undefined。这相当于只调用foo.bind(this),这可能不是你想要的。