In short: I would like to bind the result of .bind as an arguement in it's own call
var bound = foo.bind(this,bound);
because I'm not sure how else to solve my problem.
The problem:
I have an item that is dependent on an array of other items. Once one of those items is removed I want to remove the dependent item, and remove all the listeners placed on the dependencies.
I'm struggling to remove the eventhandlers of the other dependencies. I'm trying to use bind, but since the handler function is the one that removes the listeners, I find that I would have to bind the result of the bind()
call in it's own call as an argument. This does ofcourse not work.
The bind call bellow binds the unbound version of 'handler' as a parameter, and thus removeEventListener does not work as it is a different copy of the function.
The question is: can I use bind to do this and/or how can I otherwise solve this?
Im using eventemitter3, but it should be the same for any event library.
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);
});
}
edit:
Complete working example to run in 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");