简体   繁体   English

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

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

Complete node.js beginner here. 在此处完成node.js初学者。 I saw this "hello world" example somewhere 我在某个地方看到了这个“ 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/");

Really simple code in which the server responds to HTTP requests with a simple HTTP response with plain text "Hello World" 真正简单的代码,其中服务器使用纯文本“ Hello World”的简单HTTP响应来响应HTTP请求

I also ready about a library to make HTTP requests from javascript 我还准备好一个库,以通过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);
});

Here you make an HTTP request with some options and then do something with the response in a callback. 在这里,您可以使用一些选项发出HTTP请求,然后对回调中的响应进行处理。

If one was to make such an API request when an HTTP request comes to the node.js server, what happens? 如果当HTTP请求到达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? 由于流必须是单线程的,因此如何在HTTP API请求的回调中更改node.js发送到客户端的响应状态? Won't the response be sent to the event loop already by then? 届时响应是否已发送到事件循环? 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? 如何在该系统中模拟同步请求,以便您可以使用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? 由于流必须是单线程的,因此如何在HTTP API请求的回调中更改node.js发送到客户端的响应状态?

Because the response isn't sent synchronously with the request having been received. 因为响应不是与已接收到的请求同步发送的。

Won't the response be sent to the event loop already by then? 届时响应是否已发送到事件循环?

The response isn't sent until you call res.send or similar, which doesn't have to be in the same job from the job queue that triggered your request callback — and frequently isn't. 除非您调用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? 如何在该系统中模拟同步请求,以便您可以使用API​​请求的响应将响应发送给客户端?

There's no need to, and doing so would kill throughput. 无需这样做,这样做会导致吞吐量下降。

On any given thread (and NodeJS uses only one), JavaScript works on the basis of a job queue : The single JavaScript thread works by picking up a job from the queue, running the code for it all the way through, and then picking up the next job from the queue (or idling until one is added). 在任何给定线程上(NodeJS仅使用一个),JavaScript均基于作业队列工作 :单个JavaScript线程的工作方式是从队列中拾取作业,一直运行代码,然后进行拾取队列中的下一个作业(或闲置直到添加一个)。 When an event comes in or similar, if you've set up a handler for that event, a call to your handler is added to the job queue. 当发生事件或类似事件时,如果您为该事件设置了处理程序,则对处理程序的调用将添加到作业队列中。 (There are actually at least two layers to the job queue; see this answer for more on that if you're interested.) (实际上,作业队列至少有两层;如果您有兴趣,请参阅此答案以获取更多信息。)

It's absolutely fine if you don't respond to the "We got an HTTP request" from within the code for the job that called your handler. 如果您不从调用您的处理程序的工作的代码中响应“我们收到HTTP请求”,那绝对没问题。 That's perfectly normal. 完全正常。 The job and the request are completely disassociated from each other. 作业和请求完全彼此分离。 And so it's fine (and normal) if you start an asynchronous process (like a get , or a readFile ). 因此,如果您启动异步进程(如getreadFile ),那就很好(并且是正常的)。 Later, when the result of that process is available, a new job gets added to the queue, the JavaScript thread picks it up, and you use res.send or similar to reply to the request that's been waiting. 稍后,当该过程的结果可用时,一个新的作业将被添加到队列中,JavaScript线程将其拾取,然后您使用res.send或类似的方法来答复正在等待的请求。

This is how NodeJS manages high throughput despite having only a single thread: If you use asynchronous I/O throughout, your actual code doesn't have to occupy the thread for all that long, because it doesn't wait for the I/O to complete. 这是NodeJS即使只有一个线程也可以管理高吞吐量的方式:如果您始终使用异步I / O,则您的实际代码不必这么长时间就占用线程,因为它不需要等待I / O去完成。 It can do more work on other things while the I/O is pending, and then respond to it when the I/O completes. 在I / O待处理时,它可以做其他事情,然后在I / O完成时对其做出响应。

You need to change your code like this: 您需要像这样更改代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 node.js如何集群,redis,单线程和非阻塞i / o如何工作? - How does node.js clusters, redis, single thread and non blocking i/o works? 节点-等待周期内的请求响应 - Node - Wait request response within cycle For 如何使用 js o react 捕获 401 响应或请求的标头? - How to capture the headers of a 401 response or request with js o react? 如何在 Node.js 上的控制器或外部文件上使用 Web 套接字? 我无法访问 io 对象 - How to use a web socket on a controller o external file on Node.js? i can't access to io object 如何从不在npm中的外部js获取响应(节点模块) - How to get response from external js which is not in npm (node modules) 如何在其他文件 Node js(Express) 中访问请求和响应 object - How do I access Request and Response object in other files Node js(Express) Node.js - 如果在 I/O 和回调仍在运行时调用 response.end 会发生什么? - Node.js - what happens if I call response.end while I/O and callbacks are still running? 对外部 API 的相同请求适用于 go、postman、curl,但不适用于 node.js - The same request to external API works in go, postman, curl, but doesn't work in node.js 节点js | 使用外部文件作为响应发送? - Node js | Use external file to send as response? 如何使Node.js等待来自大型请求的响应 - How to make Node.js wait for response from a large request
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM