Javascript node js中的请求-响应周期如何与外部I/O协同工作

Javascript node js中的请求-响应周期如何与外部I/O协同工作,javascript,node.js,rest,http,event-driven,Javascript,Node.js,Rest,Http,Event Driven,在这里完成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, respo

在这里完成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请求时使用纯文本“Hello World”的简单HTTP响应

我还准备好了一个从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请求的响应向客户端发送响应

由于流必须是单线程的,如何在HTTP API请求的回调中更改node.js发送给客户端的响应的状态

因为响应不是与已接收的请求同步发送的

到那时,响应不是已经发送到事件循环了吗

在调用
res.send
或类似命令之前,不会发送响应,该命令不必位于触发请求回调的作业队列中的同一个作业中,而且通常不会

如何在该系统中模拟同步请求,以便使用API请求的响应向客户端发送响应

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

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

如果您没有从调用处理程序的作业的代码中响应“We got a HTTP request”,这是绝对正确的。这很正常。作业和请求彼此完全分离。因此,如果启动一个异步进程(如
get
,或
readFile
),这是正常的。稍后,当该过程的结果可用时,一个新作业被添加到队列中,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);
});