【问题标题】:How the request response cycle in node js works with external I/Onode js 中的请求响应周期如何与外部 I/O 协同工作
【发布时间】:2018-09-19 14:43:54
【问题描述】:

在这里完成 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/");

非常简单的代码,其中服务器使用带有纯文本“Hello World”的简单 HTTP 响应来响应 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 请求的响应向客户端发送响应?

【问题讨论】:

    标签: javascript node.js rest http event-driven


    【解决方案1】:

    既然流程必须是单线程的,那么如何在HTTP API请求的回调中改变node.js发送给客户端的响应状态?

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

    到那时响应不会发送到事件循环吗?

    只有在您调用 res.send 或类似名称后才会发送响应,该响应不必与触发您的请求回调的作业队列中的同一作业相同——而且通常不是。

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-12
        • 2011-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多