I'm trying to understand the best way to use events (i.e. Node's EventEmitter
) and promises in the same system. I love the idea of decoupled components that communicate loosely through some sort of central event hub. When one component has some information that might be relevant to another component it can emit it on the hub. The components generating the information need to know nothing about the components that are consuming the information.
But sometimes the interaction is more of a request/response behaviour for which promises seem more ideal. I am wondering if there is a way to unify these methods of communication.
For example, I could have a component that has a encrypted message and needs it decrypted. I want a loose coupling between the component that is doing something with the message and the component handing the message decryption. Using promises provide a nice interaction for request/response but represents tight coupling. For example:
message = ... some encrypted message ...
decrypting_lib.decrypt(message).then(function(decrypted_message) {
... do something with decrypted_message ...
})
But as you can see I have a tight coupling by referencing the decryption library. With events I can remove that coupling but the code seems more awkward:
message = ... some encrypted message ...
callback = function(decrypted_message) {
if( message.id != decrypted_message.id ) return;
hub.removeListener('message:decrypted', callback);
... do something with decrypted_message ...
}
hub.on('message:decrypted', callback);
hub.emit('message:decrypt', message);
In the second example, we emit a message to ask for the message to be decrypted while listening for it to be decrypted. Of course since other messages could be decrypted that may not be the message we are looking for we need to check for that. We also need to stop listening once we found the message we are interested in.
As you can see we now are decoupled from whatever is doing the decryption but our code is MUCH more complicated. My ideal API would allow the EventEmitter-style interface for when our code doesn't require a request/response type interaction. But when it does have a request/response interaction it would look something like:
hub.on('message:decrypt', message).then(function(decrypted_message) {
... do something with decrypted_message ...
});
In this example the decryption library would decrypt the message then emit an event to indicate a message was decrypted. This would notify all parties that are interested in any message being decrypted. But it would also call the promise that was passed in which started the process.
Is there any library out there that does something like this. Or perhaps someone more experienced with JS applications could provide a better way to do what I am trying to do.