nodejs是否代表Reactor或Proactor设计模式?

时间:2019-06-24 15:39:44

标签: node.js design-patterns architecture reactor

许多在线文章都将nodejs演示为反应堆模式的示例。它不是前摄者吗?

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

  1. reactor handles events in a single thread (synchronously)
  2. proactor handles events is multiple threads (asynchronously) with completion callbacks

例如在this article中:

  

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

它不是对proactor的定义吗?

2 个答案:

答案 0 :(得分:1)

我对Proactor设计模式不熟悉。看了一点之后,我想我理解您的困惑。

  

许多在线文章都将nodejs演示为反应堆模式的示例

这是真的。

  

它不是对proactor的定义吗?

这也是事实。

不同之处在于您的观点。

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

    numberOfEvents = select(numberOfWaits, read, write, err, timeout);

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

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

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

您可能认识到这听起来很像Proactor设计模式。实际上是这样。

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

node.js中编写的Javascript程序是Proactor设计模式的示例。

答案 1 :(得分:0)

区别与多线程无关。如下:

  • 反应堆-我想从套接字读取数据,因此我订阅了一种数据可用事件,并且当它通过同步读取可用量向其触发 react 时,< / li>
  • Proactor-我想从套接字读取数据,因此我启动了读取操作(一个主动读取数据,而无需等待我对其可用性作出反应),并订阅某种读取已完成通知,其中读取的数据可立即提供给我。

Node具有两种API,例如stream.ReadableStream#readable / stream.ReadableStream#read是Reactor界面,而 fs.readFile是Proactor。