我正在努力使自己在nodejs中创建非阻塞的繁重计算。请看以下示例(从其他内容中剔除):
http.createServer(function(req, res) {
console.log(req.url);
sleep(10000);
res.end('Hello World');
}).listen(8080, function() { console.log("ready"); });
可以想象,如果我同时打开2个浏览器窗口,第一个将等待10秒,另一个将等待20秒,这与预期的一样。因此,在知道回调以某种方式是异步的情况下,我删除了 sleep ,而将其改为:
doHeavyStuff(function() {
res.end('Hello World');
});
具有简单定义的功能:
function doHeavyStuff(callback) {
sleep(10000);
callback();
}
那当然是行不通的...我也曾尝试定义一个EventEmitter并向其注册,但是例如,发射器的主要功能在发出“完成”之前已在内部休眠,因此所有内容都会再次运行。
我想知道这里其他人如何编写非阻塞代码...例如mongojs模块或child_process.exec是非阻塞的,这意味着在代码中的某个地方,他们在另一个线程上派生了一个进程并监听其进程事件。我该如何复制这个方法,例如要花费很长的时间呢?
我是否完全误解了nodejs范例? :/
谢谢!
更新:解决方案(某种)
感谢您对Linus的回答,确实唯一的方法是产生一个子进程,例如另一个节点脚本:
http.createServer(function(req, res) {
console.log(req.url);
var child = exec('node calculate.js', function (err, strout, strerr) {
console.log("fatto");
res.end(strout);
});
}).listen(8080, function() { console.log("ready"); });
calculate.js可以花点时间去做它需要做的事情并返回。这样,可以并行运行多个请求。
最佳答案
如果不使用节点中的某些IO模块(例如fs
或net
),则无法直接执行此操作。如果您需要进行长时间运行的计算,建议您在子进程(例如child_process.fork
)或队列中进行。