简体   繁体   English

统一事件和承诺是 JS/Node

[英]Unifying Events and Promises is JS/Node

I'm trying to understand the best way to use events (ie Node's EventEmitter ) and promises in the same system.我试图了解在同一系统中使用事件(即 Node 的EventEmitter )和承诺的最佳方式。 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.使用 Promise 为请求/响应提供了很好的交互,但表示紧密耦合。 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.当我们的代码不需要请求/响应类型交互时,我理想的 API 将允许 EventEmitter 风格的接口。 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.或者,也许对 JS 应用程序更有经验的人可以提供更好的方法来做我想做的事情。

If you want to have things decoupled with events, and on the other side want to have convenient promise based interface.如果您希望将事物与事件解耦,另一方面希望拥有方便的基于 Promise 的接口。 The only way I think it can be achieved, is via introduction of other utility that would bind both eg我认为它可以实现的唯一方法是通过引入其他可以绑定两者的实用程序,例如

hub.registerForDecryption = function (message) {
  hub.emit('message:decrypt', message);
  return new Promise(function (resolve, reject) {
    hub.on('message:decrypted', function (decrypted) {
      if (message.id !== decrypted.id) return;
      resolve(decrypted);
    });
  });
};
...
hub.registerForDecryption(message).then(function (decrypted) {
  .. do something with decrypted_message ...
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM