Lets suppose that instead of wanting to trigger a linear set of functions such as the core Node.js EventEmitter, you wanted to be able to trigger events as a (potentially cyclic) directed graph.
Scenario 1. A causes B & C to fire
A
├─B
│
└────C
Scenario 2. A causes B & C to fire. B causes D to fire
A
├──B
│ └─D
└────C
This could be implemented by modifying the underlying EventEmitter (in this example EventEmitter3 thusly:
EventEmitter.prototype.connect = function (in, out) {
var self = this;
this.on(in, function () {
var args = Array.prototype.slice.call(arguments);
args.unshift(out);
self.emit.apply(self, args);
});
return this;
};In this way we could then setup the above scenarios:
Scenario 1. A causes B & C to fire
var emitter = new EventEmitter();
emitter.on('A', function a() { console.log('A fired'); });
emitter.on('B', function b() { console.log('B fired'); });
emitter.on('C', function c() { console.log('C fired'); });
emitter.connect('A', 'B');
emitter.connect('A', 'C');Scenario 2. A causes B & C to fire. B causes D to fire
var emitter = new EventEmitter();
emitter.on('A', function a() { console.log('A fired'); });
emitter.on('B', function b() { console.log('B fired'); });
emitter.on('C', function c() { console.log('C fired'); });
emitter.on('D', function c() { console.log('C fired'); });
emitter.connect('A', 'B');
emitter.connect('A', 'C');
emitter.connect('B', 'D');We could implement disconnect but we would have to add a naming convention to our functions in .connect() and implment .disconnect():
EventEmitter.prototype.connect = function (in, out) {
var self = this,
listener;
listener = function () {
var args = Array.prototype.slice.call(arguments);
args.unshift(out);
self.emit.apply(self, args);
};
listener.name = [in, out].join('_');
this.on(in, listener);
return this;
};
EventEmitter.prototype.unconnect = function (in, out) {
var name = [in, out].join('-'),
self = this;
this.listeners(in)
.filter(function (fn) {
return fn.name === name;
})
.forEach(function (fn) {
self.removeListener(in, fn);
});
return this;
};