许多在线文章都将nodejs演示为反应堆模式的示例。它不是前摄者吗?
据我了解,两者之间的区别是:
例如在this article中:
Reactor Pattern是Node.js中非阻塞I / O操作的想法。该模式提供了与每个I / O操作关联的处理程序(对于Node.js,是回调函数)。生成I / O请求后,会将其提交给多路分解器。
它不是对proactor的定义吗?
答案 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)
区别与多线程无关。如下:
Node具有两种API,例如stream.ReadableStream#readable / stream.ReadableStream#read是Reactor界面,而 fs.readFile是Proactor。