Javascript 事件发射器与并行执行的承诺?

Javascript 事件发射器与并行执行的承诺?,javascript,promise,eventemitter,Javascript,Promise,Eventemitter,我正在制作一系列模块,每个模块都需要在不同阶段运行代码。我可以用承诺。每个阶段都是这样: const phase1promise = Promise.all([module1.phase1(),module2.phase1()]); phase1promise.then(// do next phases) 或者,我可以使用一个来自“主”模块的事件发射器,子模块监听该事件发射器,以便知道何时运行阶段代码。反过来,主模块将监听这些子模块的事件发射器,以了解它们在该阶段何时完成。我安装了这个事件发

我正在制作一系列模块,每个模块都需要在不同阶段运行代码。我可以用承诺。每个阶段都是这样:

const phase1promise = Promise.all([module1.phase1(),module2.phase1()]);
phase1promise.then(// do next phases)

或者,我可以使用一个来自“主”模块的事件发射器,子模块监听该事件发射器,以便知道何时运行阶段代码。反过来,主模块将监听这些子模块的事件发射器,以了解它们在该阶段何时完成。我安装了这个事件发射器系统,它正在工作,但我开始认为承诺可能会更好,特别是对于并行运行的代码。此外,也许承诺可以被视为更标准的模式。想法?

使用事件处理多次发生的事情-对于顺序数据,使用更特殊类型的事件发射器:流

对曾经发生过的事情使用承诺

承诺是通过请求-响应设计模式设计的。你基本上:

doSomething.then(processResponse);
使用async/await,Promissions已成为执行各种类型请求响应的非常强大的工具:并行、串行、批处理等:

// Parallel
results = await Promise.all(a,b,c);

// Serial
for (i=0; i<tasks.length; i++) {
    results.push(await tasks[i]());
}

// Batch 10 tasks in parallel
for (i=0; i<tasks.length; i += 10) {
    currentTasks = tasks.splice(0,10);
    results.push.apply(results, await Promise.all(currentTasks.map(t => t())))
}
//并行
结果=等待承诺。全部(a、b、c);
//连载
对于(i=0;i来说,如果每个模块只有一个“开始”事件和一个“结束”事件,并且有一个主编排来协调所有这些,那么承诺(到目前为止!)会更简单


如果模块应该向主模块注册它们自己和/或为不同的部分发出多个事件,那么您将有更大的灵活性(并且耦合性会稍微降低),但这是一个更复杂的系统,不太容易理解-需要查看所有文件以找出依赖关系图。

挑剔:承诺和事件发射器都不会并行运行代码:JS是单线程的,只有工作者除外。也许这就是答案……或者/或者工作原理相同,只是风格/惯例问题。。。因此,它不是一个讨论论坛或征求意见的论坛。您需要编辑您的问题以提出特定的问题,该问题将返回解决该问题的特定答案。Does
module1.phase1()
执行一些异步操作,并且它返回的承诺与该异步操作相关联?如果不是,那么
promise.all()
在这里根本没有任何好处。如果是这样,那么底层异步操作可能能够在其本机代码实现中获得一些并行性(这取决于它们是如何实现的).Events和promises对并行性没有影响。两者都只是通知系统。它们实际上并不运行代码,只是在事情完成时通知。是的,我想说模块将执行异步任务(我想强制阶段从完成到开始).我想我会装配这两个系统并比较基准…尽管我认为它们彼此非常接近。这是一个很好的答案。可能不清楚的细微差别是,多次发生的操作仍然可以使用承诺,但它们每次只需要发出新的承诺。我想你在很大程度上涵盖了这一点,但如果你真的d“对发生过的事情使用承诺”。这可能会被误解。@Evert是的。从技术上讲,您可以在while循环中等待来模拟事件,但这会非常笨拙。更不用说,这意味着外部异步函数永远不会解析。除非您指的是称为mu的一次性事件多次。它们仍然是只发生一次的事件,但您恰好创建了许多。是的,我指的是后者。例如,如果我进行多个API调用,它们仍然使用您提到的请求/响应范例。谢谢@slebetman。现在所有这些模块都在做客户端工作,没有网络通信。我已经用worker进行了实验但是所有这些模块都需要DOM访问。@TedFitzpatrick是的。Windows上的Mac GUI开发和.Net开发以及Linux/Unix GUI开发(wxWindows、Gnome、Gtk等)都存在同样的问题。UI线程不能拆分。因此,所有UI进程都必须在单个线程中完成。您可以拆分要交叉的任务(做一件事,停下来再做另一件事,停下来再继续之前的任务等)但这不会使它们并行发生,只能在时间上均匀分布。对于这种“多任务”你可以简单地用
setTimeout
setInterval
来实现它们。这样做的主要原因是避免阻塞/冻结UIT。这是一个有趣的点,它能够发出比我的相位控制通信更多的事件。这可能是另一个场景的六分之一。我想我将装配promises系统并比较速度基准。谢谢@Bergi!!@TedFitzpatrick速度基准?这东西在启动时只运行一次进行初始化-你不会注意到任何差异。@TedFitzpatrick和是的,我实际上是指能够为“模块的子阶段”发出多个事件-不是相位控制之外的事件。哈哈,是的,在速度方面,它们很可能是可比的。只是尽我所能制作“最佳”版本。了解模块的子短语,以后可以购买灵活性。有趣。发射系统加载1659ms,承诺系统加载1813ms。因为它(稍微)更快,同时也考虑到未来的灵活性,我将使用发射器。