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

时间:2022-10-19 18:28:12

I want to know how the engine in node.js know when to call and execute the queued operation. I understand that node.js is single threaded and uses asynchronous non-blocking to execute operations.

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

But let's say you are calling something from the database and node.js queues the operation and doesn't wait for this to execute further lines of code. Being single thread it stores the data in channels(if I am not wrong). But how does the server know that the network isn't busy and it is the right time to execute the queued operation.

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

Or it executes the queued operation at the end of the program. This can't be the case. So I am curious to know what happens under the hood and how does the node server know when to execute the queued operation.

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

2 个解决方案

#1


1  

It's not clear what you mean by "channels" as that is not a built-in node.js concept or a term that is used internally to describe how node.js works. The tutorial you reference in your comment is talking about the Java language, not the Javascript language so it has absolutely nothing to do with node.js. The concept of "channels" in that tutorial is something that that specific NIO library implements in Java.

目前还不清楚“通道”是什么意思,因为它不是内置的node.js概念,也不是内部用来描述node.js如何工作的术语。您在评论中引用的教程是谈论Java语言,而不是Javascript语言,因此它与node.js完全无关。该教程中“通道”的概念是特定NIO库在Java中实现的。

But, if you're really just asking how async operations work in node.js, I can explain that generaly concept.

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

node.js works off an event queue. The node.js interpreter grabs the next event in the event queue and executes it (typically that involves calling a callback function). That callback function runs (single threaded) until it returns. When it returns, the node.js interpreter then looks in the event queue for the next event. If there are any, it grabs that next event and calls the callback associated with it. If there are not events currently in the event queue, then it waits for an event to be put in the event queue (with nothing to do expect perhaps runs some garbage collection).

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

Now, when you runs some sort of asynchronous operation in your Javascript (such as a DB query), you can your db query function, that initiates the query (by sending the query off to the database) and then immediately returns. This allows your piece of Javascript that started that query to then return and give control back to node.js.

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

Meanwhile, some native code is managing the connection to your database. When the response comes back from the database, an event is added to the internal node.js event queue.

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

Whenever the node.js interpreter has finished running other Javascript, it looks in the event queue and pulls out the next event and calls the callback associated with that. In that way, your DB query result gets processed by your code. In all cases here, an asynchronous operation has some sort of callback associated with it that the interpreter can call when it finds the event in the event queue.

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

Being single thread it stores the data in channels(if I am not wrong).

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

node.js doesn't have a "channels" concept so I'm not sure what you meant by that.

node.js没有“渠道”概念,所以我不确定你的意思。

Or it executes the queued operation at the end of the program.

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

When the result comes back from the database, some native code managing that will insert an event into the node.js event queue. The Javascript interpreter will service that event, then next time it gets back to the event loop (other Javascript has finished running and it's time to check for the next event to process).

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

It's important to understand that initiating an asynchronous operation is non-blocking so you get this:

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

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");

Because of the non-blocking nature of things, this will log:

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

1
3
2

Some other references on the topic:

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

How does JavaScript handle AJAX responses in the background?

JavaScript如何在后台处理AJAX响应?

Where is the node.js event queue?

node.js事件队列在哪里?

Understanding Call backs

了解回电

Why does a while loop block the node event loop?

为什么while循环会阻塞节点事件循环?

#2


0  

Node internally uses the underlying operating systems non-blocking io API-s. See overlapped io, WSAEventSelect for Windows, select for Linux.

Node内部使用底层操作系统非阻塞io API-s。请参阅重叠的io,WSAEventSelect for Windows,选择Linux。

#1


1  

It's not clear what you mean by "channels" as that is not a built-in node.js concept or a term that is used internally to describe how node.js works. The tutorial you reference in your comment is talking about the Java language, not the Javascript language so it has absolutely nothing to do with node.js. The concept of "channels" in that tutorial is something that that specific NIO library implements in Java.

目前还不清楚“通道”是什么意思,因为它不是内置的node.js概念,也不是内部用来描述node.js如何工作的术语。您在评论中引用的教程是谈论Java语言,而不是Javascript语言,因此它与node.js完全无关。该教程中“通道”的概念是特定NIO库在Java中实现的。

But, if you're really just asking how async operations work in node.js, I can explain that generaly concept.

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

node.js works off an event queue. The node.js interpreter grabs the next event in the event queue and executes it (typically that involves calling a callback function). That callback function runs (single threaded) until it returns. When it returns, the node.js interpreter then looks in the event queue for the next event. If there are any, it grabs that next event and calls the callback associated with it. If there are not events currently in the event queue, then it waits for an event to be put in the event queue (with nothing to do expect perhaps runs some garbage collection).

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

Now, when you runs some sort of asynchronous operation in your Javascript (such as a DB query), you can your db query function, that initiates the query (by sending the query off to the database) and then immediately returns. This allows your piece of Javascript that started that query to then return and give control back to node.js.

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

Meanwhile, some native code is managing the connection to your database. When the response comes back from the database, an event is added to the internal node.js event queue.

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

Whenever the node.js interpreter has finished running other Javascript, it looks in the event queue and pulls out the next event and calls the callback associated with that. In that way, your DB query result gets processed by your code. In all cases here, an asynchronous operation has some sort of callback associated with it that the interpreter can call when it finds the event in the event queue.

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

Being single thread it stores the data in channels(if I am not wrong).

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

node.js doesn't have a "channels" concept so I'm not sure what you meant by that.

node.js没有“渠道”概念,所以我不确定你的意思。

Or it executes the queued operation at the end of the program.

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

When the result comes back from the database, some native code managing that will insert an event into the node.js event queue. The Javascript interpreter will service that event, then next time it gets back to the event loop (other Javascript has finished running and it's time to check for the next event to process).

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

It's important to understand that initiating an asynchronous operation is non-blocking so you get this:

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

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");

Because of the non-blocking nature of things, this will log:

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

1
3
2

Some other references on the topic:

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

How does JavaScript handle AJAX responses in the background?

JavaScript如何在后台处理AJAX响应?

Where is the node.js event queue?

node.js事件队列在哪里?

Understanding Call backs

了解回电

Why does a while loop block the node event loop?

为什么while循环会阻塞节点事件循环?

#2


0  

Node internally uses the underlying operating systems non-blocking io API-s. See overlapped io, WSAEventSelect for Windows, select for Linux.

Node内部使用底层操作系统非阻塞io API-s。请参阅重叠的io,WSAEventSelect for Windows,选择Linux。