Nodejs代表的是Reactor还是Proactor设计模式?

use*_*761 4 architecture design-patterns reactor node.js

网上有很多文章将 NodeJS 演示为反应器模式的示例。这不是相当积极主动吗?

据我了解,两者的区别是:

  1. reactor 在单个线程中处理事件(同步)
  2. 前摄器处理事件是带有完成回调的多线程(异步)

例如在这篇文章中:

Reactor 模式是 Node.js 中非阻塞 I/O 操作的一种思想。该模式提供了一个与每个 I/O 操作关联的处理程序(对于 Node.js,是一个回调函数)。当生成 I/O 请求时,会将其提交给解复用器。

这实际上不是proctor的定义吗?

sle*_*man 5

我不熟悉 Proactor 设计模式。阅读了一些相关内容后,我想我理解您的困惑。

网上很多文章都以nodejs作为反应器模式的例子进行演示

这是真实的。

这实际上不是proctor的定义吗?

这也是事实。

区别在于你的观点。

在内部,节点的事件循环是一个阻塞调用(讽刺的是)。这只是使用非阻塞 I/O 的最有效方法。不同的操作系统有不同的函数来请求操作系统在您感兴趣的事情发生时唤醒您的进程。由于 POSIX 要求,有一个所有现代操作系统都支持的跨平台 API select():. Node.js 实际上使用 libuv,它会根据目标平台在编译时自动选择正确的 API。但出于本答案的目的,我们将重点关注select(). 让我们看看select()

    numberOfEvents = select(numberOfWaits, read, write, err, timeout);
Run Code Online (Sandbox Code Playgroud)

select()函数会阻塞长达几timeout毫秒,或者读取、写入或出错的文件/套接字发生某种情况。只需一个函数,操作系统就提供了足够的功能来实现大多数 Node.js,例如定时器setTimeout()setInterval()监听网络套接字。使用select()事件循环看起来像这样:

// Pseudocode:

while(1) {
    evaluateJavascript();
    timeout = calculateTimers();
    events = select(n, read, write, err, timeout);
    if (events > 0 || timersActive()) {
        getCallbacks(events, read, write, err, timers());
    }
}
Run Code Online (Sandbox Code Playgroud)

这基本上是一个 Reactor 设计模式。

然而,节点在其实现中隐藏了这一点。它向 Javascript 程序员公开的是一组 API,用于注册回调并在事件发生时调用这些回调。这部分是历史性的(浏览器 API 就是这样设计的),部分是实用性的(这是一个更加灵活的架构 - 几乎所有 GUI 框架,从 GTK 到 wxWindows 到 .Net 都是这样工作的)。

您可能会意识到这听起来很像 Proactor 设计模式。事实上确实如此。

所以node.js本身就是Reactor设计模式的一个例子。

用 Node.js 编写的 JavaScript 程序是 Proactor 设计模式的示例。