NodeJS如何实现“非阻塞”?


14

我正在学习NodeJS,只是想澄清一些东西。到目前为止,在几本入门教程和书籍中,它们很早就描述了Node的“非阻塞”体系结构-或者说有可能(并建议整个观点)以非阻塞方式进行编码。

因此,例如,在我正在阅读以异步方式从数据库获取数据的书中给出了此示例。

http.createServer(function (req, res) {
  database.getInformation(function (data) {
      res.writeHead(200);
      res.end(data);
  });
});

据我所知,发生的事情是Node调用了数据库,然后继续处理调用堆栈中下一步可能发生的任何事情。数据库请求完成后,将填充匿名回调函数中的数据变量,并将该函数添加到调用堆栈中(并在Node到达该堆栈时执行)。

我的问题是,究竟在处理数据库请求是什么?当然,Node必须同时阻止吗?负责数据库请求的是什么?或者,如果Node在等待对外部资源的异步HTTP GET请求,那么该请求又在做什么呢?

Answers:


17

当Node.js被描述为“非阻塞”时,这特别意味着其IO为非阻塞。Node使用libuv以与平台无关的方式处理其IO。在Windows上,它使用IO完成端口,在Unix上,它使用epoll / kqueue / select / etc。因此,它发出一个非阻塞的IO请求(它可能具有后台线程监视,但是永远不会暴露给JavaScript),结果,它在事件循环中将其排队,该循环在主线程上调用JavaScript回调(阅读:仅)JavaScript线程。

对于数据库,这取决于库的编写方式。如果它使用HTTP进行通信(就像某些NoSQL数据库一样),则可以使用标准节点http库以纯JavaScript轻松编写它。如果这样做是另一种方式,那完全取决于库。只要抽象永远不会暴露给JavaScript,就可以用C / C ++编写并使用后台线程。

关于您要“处理”数据库请求的问题,理想情况下,应该做的就是向库发送一条简单消息(例如,SQL语句或其他查询或连接请求),然后使用JavaScript一直在努力。当库准备好发回消息时,它会将消息发回到运行回调的节点的事件队列,从而使该代码段得以运行。


net当http不可用时,有软件包。
Florian Margaine 2013年

详细信息可能会有所帮助。Node利用了V8 JS引擎。V8的最佳功能之一是易于将C / C ++进程绑定到JS调用。JavaScript函数正在阻塞,但是所有函数所做的就是在不阻塞的情况下调用某些东西。然后,当该过程完成时,另一个JS函数将做出响应。JS函数互相阻塞意味着您永远不会有两件事试图做某事,例如将一次写入同一时间安排到同一文件位置,这是我假设需要管理多线程的地方。始终很清楚,哪个请求首先出现是为了排队。
埃里克·雷彭
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.