简体   繁体   English

如何等待直到多个EventEmitter实例在Node.js中发出同一事件?

[英]How to wait until multiple EventEmitter instances have emitted same event in Node.js?

I'm working on a Node.js module/utility which will allow me to scaffold some directories/files. 我正在开发一个Node.js模块/实用程序,它将允许我搭建一些目录/文件。 Long story short, right now I have main function which looks something like this: 长话短说,现在我有了主要功能,如下所示:

util.scaffold("FileName")

This "scaffold" method returns an EventEmitter instance, so, when using this method I can do something like this: 此“脚手架”方法返回一个EventEmitter实例,因此,使用此方法时,我可以执行以下操作:

util.scaffold("Name")
.on("done", paths => console.log(paths)

In other words, when all the files are created, the event "done" will be emitted with all the paths of the scaffolded files. 换句话说,当创建所有文件时,事件“完成”将与支架文件的所有路径一起发出。

Everything good so far. 到目前为止一切都很好。

Right now, I'm trying to do some tests and benchmarks with this method, and I'm trying to find a way to perform some operations (assertions, logs, etc) after this "scaffold" method has been called multiple times with a different "name" argument. 现在,我正在尝试使用此方法进行一些测试和基准测试,并试图找到一种方法来多次调用此“脚手架”方法后执行一些操作(断言,日志等)不同的“名称”参数。 For example: 例如:

const names = ["Name1", "Name2", "Name3"] 
const emitters = names.map(name => {
return util.scaffold(name)
})

If I was returning a Promise instead of an EventEmitter, I know that I could do something like this: 如果我返回的是Promise而不是EventEmitter,我知道我可以做这样的事情:

Promise.all(promises).then(()=> {
//perform assertions, logs, etc
})

However, I'm not sure how can I do the equivalent using EventEmitters. 但是,我不确定如何使用EventEmitters进行等效操作。 In other words, I need to wait until all these emitters have emitted this same event (ie "done") and then perform another operation. 换句话说,我需要等到所有这些发射器都发出同一事件(即“完成”),然后再执行其他操作。

Any ideas/suggestions how to accomplish this? 有什么想法/建议如何做到这一点?

Thanks in advance. 提前致谢。

With promise.all you have a unique information when "everything" is done. 有了promise.all,当“一切”完成后,您将获得唯一的信息。 Of course that is when all Promises inside are fullfiled/rejected. 当然那是当内部所有承诺都已完成/被拒绝的时候。

If you have an EventEmitter the information when "everything" is done can not be stored inside your EventEmitter logic because it doesn't know where or how often the event is emmited. 如果您有EventEmitter,则完成“所有操作”后的信息将无法存储在您的EventEmitter逻辑中,因为它不知道在何处或多久发出一次事件。

So first solution would be to manage an external state "everything-done" and when this changes to true you perform the other operation. 因此,第一个解决方案是管理“一切都已完成”的外部状态,当此状态变为true时,您将执行其他操作。

So like promise.all you have to wrap around it. 因此,就像promise.All,您必须将其环绕。

The second approach i could imagine is a factory where you build your EventEmitters that keeps track of the instances. 我可以想象的第二种方法是在工厂中构建EventEmitters,以跟踪实例。 Then this factory could provide the information whether all instances have been fired. 然后,该工厂可以提供是否已触发所有实例的信息。 But this approach could fail on many levels: One Instance->many Calls; 但是这种方法可能会在很多层面上失败:一个实例->多次调用; One Instance->no Call; 一实例->无呼叫; ... ...

just my 5 cent and i would be happy to see another solution 只有我的5美分,我很高兴看到另一种解决方案

The simplest approach, as mentioned by others, is to return promises instead of EventEmitter instances. 正如其他人所提到的,最简单的方法是返回promise,而不是EventEmitter实例。 However, pursuant to your question, you can write your callback for the done event as follows: 但是,根据您的问题,您可以按如下所示编写done事件的回调:

const names = ['Name1', 'Name2', 'Name3']
let count = 0
util.scaffold('Name').on('done', (paths) => {
  count += 1
  if (count < names.length) {
    // There is unfinished scaffolding
  } else {
    // All scaffolding complete
  }
})

I ended up doing what @theGleep suggested and wrapping each of those emitters inside a Promise, like this: 我结束了@theGleep的建议,并将每个发射器包装在Promise中,如下所示:

const names = ["Name1", "Name2", "Name3"] 
const promises = names.map(name => {
     return new Promise((resolve) => {
       util.scaffold(name).on("done", paths => {
       resolve(paths)})
  })
})

// and then

Promise.all(promises).then(result => {
    // more operations
})

It seems to be doing what I need so far, so I'll just use this for now. 到目前为止,它似乎可以满足我的需求,所以我现在就使用它。 Thanks everyone for your feedback :) 感谢大家的反馈意见:)

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

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