非阻塞I / O如何与通道一起工作

时间:2018-05-08 17:38:38

标签: node.js asynchronous nonblocking serverside-javascript

我想知道node.js中的引擎如何知道何时调用和执行排队操作。我知道node.js是单线程的,并使用异步非阻塞来执行操作。

但是,假设您正在从数据库中调用某些内容,node.js会对操作进行排队,并且不会等待执行更多代码行。作为单线程,它将数据存储在通道中(如果我没有错)。但是,服务器如何知道网络不忙,现在是执行排队操作的正确时间。

或者它在程序结束时执行排队操作。情况并非如此。所以我很想知道幕后发生了什么,以及节点服务器如何知道何时执行排队操作。

2 个答案:

答案 0 :(得分:1)

不清楚你的意思是什么"频道"因为它不是内置的node.js概念或内部用于描述node.js如何工作的术语。你评论中的tutorial you reference是关于Java语言,而不是Javascript语言,因此它与node.js完全无关。 "渠道"的概念在该教程中,特定NIO库在Java中实现。

但是,如果您真的只是询问node.js中的异步操作是如何工作的,我可以解释一下这个概念。

node.js处理事件队列。 node.js解释器获取事件队列中的下一个事件并执行它(通常涉及调用回调函数)。该回调函数运行(单线程)直到它返回。当它返回时,node.js解释器然后在事件队列中查找下一个事件。如果有,它会抓取下一个事件并调用与之关联的回调。如果事件队列中当前没有事件,那么它等待事件放入事件队列中(没有任何事情可以预期可能会运行一些垃圾收集)。

现在,当您在Javascript中运行某种异步操作(例如数据库查询)时,您可以使用db查询函数启动查询(通过将查询发送到数据库)然后立即返回。这允许您启动该查询的Javascript然后返回并将控制权交还给node.js。

同时,一些本机代码正在管理与数据库的连接。当响应从数据库返回时,会将一个事件添加到内部node.js事件队列。

每当node.js解释器完成运行其他Javascript时,它会查看事件队列并拉出下一个事件并调用与之关联的回调。这样,您的数据库查询结果将由您的代码处理。在这里的所有情况下,异步操作都有某种与之关联的回调,解释器在事件队列中找到事件时可以调用它。

  

作为单线程,它将数据存储在通道中(如果我没有错)。

node.js没有"频道"概念所以我不确定你的意思。

  

或者它在程序结束时执行排队操作。

当结果从数据库返回时,一些本机代码管理会将事件插入node.js事件队列。 Javascript解释器将为该事件提供服务,然后下次返回事件循环(其他Javascript已完成运行,并且是时候检查下一个要处理的事件)。

了解启动异步操作是非阻塞的非常重要,所以你得到这个:

console.log("1");
callSomeAsyncFunction(someData, (err, data) => {
    // this callback gets called later when the async operation finishes
    // and node.js gets a chance to process the event that was put
    // in the event queue by the code that managed the async operation
    console.log("2");
});

// right here there is nothing else to do so the interpreter returns back
// to the system, allowing it to process other events
console.log("3");

由于事物的非阻塞性质,这将记录:

1
3
2

关于该主题的其他一些参考文献:

How does JavaScript handle AJAX responses in the background?

Where is the node.js event queue?

Understanding Call backs

Why does a while loop block the node event loop?

答案 1 :(得分:0)

Node在内部使用底层操作系统非阻塞io API-s。请参阅overlapped ioWSAEventSelect for Windows,select for Linux。

相关问题