我需要一个Node.js事件循环的很好的比喻。

时间:2014-03-09 17:02:58

标签: javascript node.js snmp

我一直在阅读一本关于节点的好书,我讨论的是Node.js非阻塞的框架主题。我来自VB背景,因此我习惯于按顺序查看代码。对于下面的代码,关于无阻塞异步框架。这里的事件是什么,不应该事件循环拾取“for”意味着这是事件并且顺序节点在i ++ = var i之前不应该做任何事情吗?

我问的原因是我正在考虑一个SNMP服务器端应用程序,如果我告诉它要ping 10个设备,我就无法理解node.js会做什么。如果第7个IP处于脱机状态,我将不得不等到snmp超时发生在第8个之前,这是正确的吗?

var http = require('http'),
  urls = ['shapeshed.com', 'www.bbc.co.uk', 'edition.cnn.com'];

function fetchPage(url) {
  var start = new Date();
  http.get({ host: url }, function(res) {
    console.log("Got response from: " + url);
    console.log('Request took:', new Date() - start, 'ms');
  });
}

for(var i = 0; i < urls.length; i++) {
  fetchPage(urls[i]);
}

2 个答案:

答案 0 :(得分:2)

来自VB背景你有一个优势:VB也是事件驱动的!您是否曾经需要在VB代码中使用DoEvents()?这告诉VB在事件队列中运行挂起的事件。

不同之处在于,在VB中,事件通常是用户触发的并且基于UI,鼠标点击等。节点(主要是服务器端)主要围绕I / O进行事件。

您的代码永远不会被中断或阻止(除非您故意这样做)。例如,在上面的代码片段中,对http.get的调用意味着“去获取此URL,并在完成后调用此回调”。这将启动http请求并立即返回。所以你的for循环将遍历所有的URL,开始所有的get操作,然后完成。

此时从函数返回,节点返回事件循环。请求完成后,节点会将请求的回调调度到事件循环中,并最终运行回调。

要考虑一件事:如果其中一个http请求在for循环之前完成了怎么办?在这种情况下,将在事件循环上调度回调。但是你还没有回到事件循环,你仍在运行你的for循环。在从当前正在运行的任何函数返回之前,所有回调都不会执行。

对于VB程序员来说,这种“在事件处理程序中做得不太多”的建议听起来应该非常熟悉。

答案 1 :(得分:0)

没有。异步意味着I / O(如HTTP请求)不会阻塞; it is transparently handled on separate threads。致http.get的电话会立即返回 。因此,在单个字节越过线路之前,for循环实际完成(实时)。

对于http模块,请求实际上是通过Agent类在后台排队的。默认情况下,节点仅打开5个并发HTTP请求。您可以使用自定义Agent更改此内容。