Node.js中的非阻塞代码无法正常工作

时间:2012-02-11 01:22:13

标签: node.js nonblocking

我正在尝试学习如何在node.js中创建非阻塞应用程序,但我的代码似乎没有工作。

nonblocking.js

var http = require('http');
var exec = require('child_process').exec;

var userRequests = 0;
http.createServer(function (request, response) {
    userRequests++;

    response.writeHead(200, {'Content-Type': 'text/plain'});

    if( userRequests == 1 ){
        exec("node wait.js", function(){
            response.write('Thanks for waiting!');
            response.end();
        });
    }
    else{
        response.write('Hello!');
        response.end();
    }
}).listen(8080);

console.log('Server start');

wait.js

var startTime = new Date().getTime();
while (new Date().getTime() < startTime + 15000);

1 个答案:

答案 0 :(得分:2)

根据定义,您的示例涉及阻止逻辑。它可能不是阻塞的主要过程,但它仍然有点失败。

Node在浏览器中使用与JavaScript类似的事件循环。整个网络上有大量可用的资源用于了解JavaScript的工作原理。

我建议你看看这些:

关键是节点中的所有内容都是由某种事件触发的。在您发布的示例代码中,该事件是生成的进程退出。但是你不需要启动一个单独的进程来等待15秒。 节点的所有 API都是事件驱动的,基于时间的事件实际上是JavaScript本身的一部分。

以下是您将如何编写类似示例的示例:

var http = require('http'),
    userRequests = 0;

http.createServer(function (request, response) {
  userRequests++;

  response.writeHead(200, {'Content-Type': 'text/plain'});

  if( userRequests == 1 ){
    setTimeout(function(){
      response.write('Thanks for waiting!');
      response.end();
    }, 15000);
  }
  else{
    response.write('Hello!');
    response.end();
  }
}).listen(8080, function() {
  console.log('Server start');
});

您在评论中提到了文件。要发送文件,您可以这样做:

var http = require('http'),
    exec = require('child_process').exec,
    userRequests = 0;

http.createServer(function (request, response) {
  userRequests++;

  response.writeHead(200, {'Content-Type': 'text/plain'});

  if( userRequests == 1 ){
    var stream = fs.createReadStream('./somefile.txt');
    stream.on('data', function(data) {
      response.write(data);
    });
    stream.on('end', function() {
      response.end();
    });
  }
  else{
    response.write('Hello!');
    response.end();
  }
}).listen(8080, function() {
  console.log('Server start');
});

一般来说,它实际上更直接,因为你会这样做:

if( userRequests == 1 ){
  fs.createReadStream('./somefile.txt').pipe(response);
}

Node有一个标准的'stream'定义,它可以发出数据和结束事件等,而'pipe'方法会自动处理我在上面的例子中手动添加的数据和事件处理程序的绑定。

正如我所说,从阅读这些文章开始。它们非常有用,可以让你朝着正确的方向前进。