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

时间:2017-03-04 16:55:34

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

在这里完成node.js初学者。我看到了这个"你好世界"示例某处

// 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请求,会发生什么?由于流必须是单线程的,如何更改响应node.js在HTTP API请求的回调中发送给客户端的状态?不知道当时响应是否已发送到事件循环?如何在此系统中模拟同步请求,以便您可以使用API​​请求的响应向客户端发送响应?

1 个答案:

答案 0 :(得分:4)

  

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

因为响应不是与收到的请求同步发送的。

  

那时响应是否会被发送到事件循环?

在您调用res.send或类似内容之前,不会发送响应,而get或类似内容不必来自触发请求回调的作业队列中的同一作业 - 而且通常不会。

  

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

没有必要,这样做会导致吞吐量下降。

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

如果您没有从调用处理程序的作业的代码中回复“我们收到HTTP请求”,那就绝对没问题了。那是完全正常的。工作和请求完全不相互关联。因此,如果您启动异步流程(例如readFileres.send),那就很好(也很正常)。稍后,当该过程的结果可用时,新作业将添加到队列中,JavaScript线程将其拾取,并使用// Class LeftPanel: class LeftPanel extends JPanel { private JPanel leftPanel; private JComboBox<String> comboBox; //!! // !! public LeftPanel(String[] comboTexts) { leftPanel = new JPanel(); comboBox = new JComboBox<>(comboTexts); // !! leftPanel.add(comboBox); add(leftPanel); } // !! public String getComboSelection() { return comboBox.getSelectedItem().toString(); } // !! public void comboAddActionListener(ActionListener listener) { comboBox.addActionListener(listener); } } 或类似内容来回复正在等待的请求。

这就是NodeJS管理高吞吐量的方法,尽管只有一个线程:如果你在整个过程中使用异步I / O,你的实际代码不必长时间占用线程,因为它不等待I / O完成。当I / O挂起时,它可以在其他事情上做更多的工作,然后在I / O完成时对它做出响应。