node js中的请求响应周期如何与外部一起工作I/O

How the request response cycle in node js works with external I/O

完全 node.js 初学者。我在某处看到了这个 "hello world" 示例

// Load the http module to create an http server.
var http = require('http');

// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end("Hello World\n");
});

// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);

// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");

非常简单的代码,其中服务器使用纯文本的简单 HTTP 响应来响应 HTTP 请求 "Hello World"

我还准备了一个库来从 javascript

发出 HTTP 请求
http.get(options, function(resp){
  resp.on('data', function(chunk){
    //do something with chunk
  });
}).on("error", function(e){
  console.log("Got error: " + e.message);
});

此处您使用一些选项发出 HTTP 请求,然后在回调中对响应执行某些操作。

如果在 HTTP 请求到达 node.js 服务器时发出这样的 API 请求,会发生什么情况?由于流程必须是单线程的,如何在 HTTP API 请求的回调中更改发送到客户端的响应 node.js 的状态?到那时响应是否已经发送到事件循环?如何在这个系统中模拟同步请求,以便您可以使用 API 请求的响应向客户端发送响应?

Since the flow has to be single threaded, how can one change the state of the response node.js sends to the client in the callback of the HTTP API request?

因为响应没有与收到的请求同步发送。

Won't the response be sent to the event loop already by then?

在您调用 res.send 或类似的方法之前不会发送响应,它不必位于触发您的请求回调的作业队列中的同一个作业中——而且通常不是。

How can one simulate synchronous requests in this system so that you can use the response of the API request to send a response to the client?

没有必要,这样做会降低吞吐量。

在任何给定的线程上(NodeJS 只使用一个线程),JavaScript 在 作业队列的基础上工作 :单个 JavaScript 线程工作通过从队列中选取一个作业,运行 一直执行它的代码,然后从队列中选取下一个作业(或空闲直到添加一个)。当事件发生或类似事件发生时,如果您已经为该事件设置了处理程序,则对您的处理程序的调用将添加到作业队列中。 (作业队列实际上至少有两层;如果您有兴趣,请参阅 了解更多信息。)

如果您不从调用您的处理程序的作业的代码中响应 "We got an HTTP request",那绝对没问题。这是完全正常的。作业和请求彼此完全分离。因此,如果您启动异步进程(如 getreadFile),这很好(而且很正常)。稍后,当该过程的结果可用时,一个新作业将添加到队列中,JavaScript 线程将其拾取,然后您使用 res.send 或类似的方法来回复一直在等待的请求。

这就是 NodeJS 在只有一个线程的情况下管理高吞吐量的方式:如果您始终使用异步 I/O,您的实际代码不必占用线程那么久,因为它不会不要等待 I/O 完成。它可以在 I/O 挂起时做更多其他事情,然后在 I/O 完成时响应它。

您需要像这样更改您的代码:

http.get(options, function(resp){
  resp.on('data', function(chunk){
    resp.send(chunk);
  });
}).on("error", function(e){
  console.log("Got error: " + e.message);
});