Node.js中的POST正文和一些asynchronous条件检查

我想从http.ServerRequest获取请求(POST)主体,但是当我的请求函数被调用时,请不要直,而是在一段时间之后(Redis查询)。

我有一个非常简单的例子来说明:

 var http = require('http'), sys = require('sys'); http.createServer(function (req, res) { sys.puts("Got request"); req.pause(); setTimeout(function() { // In real code I'm accessing Redis here. var body = ""; req.addListener('data', function (chunk) { sys.puts("Got 'data' event"); body += chunk; }); req.addListener('end', function () { sys.puts("Got 'end' event"); res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(body); }); req.resume(); }, 10); }).listen(8000); 

在这个例子中,即使我调用了req.pause() / req.resume()dataend事件也是完全错过的,所以请求的“卡住”。

如果我注释掉setTimeout()调用,并在请求函数中做所有事情,一切都按预期工作。 但是我想查询Redis来查看请求的有效时间。 POST是大file upload,我不想浪费时间等待不成功的上传完成。

简单的方法是将POST延迟几毫秒(在我的例子中,POST需要至less几秒钟的时间,所以这么小的延迟是微不足道的)。 整洁的一个是开始parsing传入的数据,同时validation请求和丢弃连接,如果请求被发现是无效的。

问题是:我会怎么做呢? 如果这个问题,我正在使用Node.js版本0.1.97-14-g0055dd1。

感谢您的任何build议。

不知道什么时候我这样做是正确的,但是这对我来说似乎是正确的:

 var http = require('http'), sys = require('sys'); http.createServer(function (req, res) { var body = "", body_complete = false, wait_complete = false; sys.debug("Got request"); // This will be called on each process' completion var final_cb = function(err) { if (err) throw new Error(err); if (body_complete && wait_complete) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(body); } }; // Async process one: get POST body req.addListener('data', function (chunk) { sys.debug("Got 'data' event"); body += chunk; }); req.addListener('end', function () { sys.debug("Got 'end' event"); body_complete = true; final_cb(null) }); // Async process two: wait 10ms setTimeout(function() { // In real code I'm accessing Redis here. sys.debug("Timeout passed"); if (false) { // Okay, timeout can't go wrong res.writeHead(403); res.end('Sorry'); } wait_complete = true; final_cb(null); }, 10); }).listen(8000); 

另外:当连接中间件想要执行一些asynchronous请求(即将控制权交还给事件循环)时,它可以这样工作:

 var pause = utils.pause(req); fs.readFile(path, function(){ next(); pause.resume(); }); 

其中utils.pause()是一个黑客缓冲未决事件 。