繁体   English   中英

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

[英]Event Emitters vs Promises for parallel execution?

我正在制作大量模块,每个模块都需要在各个阶段运行代码。 我可以为每个阶段使用 Promise.all ,例如:

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

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

对不止一次发生的事情使用事件——对于顺序数据,使用更专业的事件发射器类型:流。

对只发生一次的事情使用 Promise。

Promise 是一种请求-响应设计模式。 你基本上:

doSomething.then(processResponse);

使用 async/await,promise 已经成为一种非常强大的工具来执行各种类型的请求-响应:并行、系列、批处理等:

// 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())))
}

但是,Promises 并非旨在拦截多个事件。 一旦 promise 解决了其 state 更改为已解决。

这就是通用事件发射器的用武之地。对于诸如 onclick 监听器之类的东西,等待网络上的请求(参见 Express.js),等待键盘输入 - 不能使用承诺(当然,除非您打算在之后停止监听更多事件处理一个事件)。

对于本质上是对某些数据的请求的事情,请使用承诺。

但请注意,这两者都只是如何管理异步进程的设计模式。 不要使函数异步。 还要注意,异步进程可能是多线程的,也可能不是多线程的。 对于网络 I/O,它们是单线程的 - javascript 基本上具有并行等待,而不是并行执行指令。 然而,有一些模块允许您启动新线程或进程(浏览器中的 web worker 和 node.js 中的 child_process)


工作线程

如果您查看 web 工作人员,您会发现 API 是基于事件的。 这是应该的,因为工作人员无法知道主进程将要求它何时以及执行多少工作。 但是您可以轻松地将自己的主进程 API 包装在 promise 中,因为它基本上是在执行请求-响应(当然,前提是每个请求只会触发工作人员仅发送一个响应)。

所以有时两者都可以 - 使用有意义的设计模式。

如果每个模块只有一个“开始”事件和一个“结束”事件,并且有一个主编排所有这些,那么 Promise 将(到目前为止)更简单。

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

暂无
暂无

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

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