Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
482 views
in Technique[技术] by (71.8m points)

node.js - NodeJs how to create a non-blocking computation

I am trying to get my head around creating a non-blocking piece of heavy computation in nodejs. Take this example (stripped out of other stuff):

http.createServer(function(req, res) {
    console.log(req.url);
    sleep(10000);
    res.end('Hello World');
}).listen(8080, function() { console.log("ready"); });

As you can imagine, if I open 2 browser windows at the same time, the first will wait 10 seconds and the other will wait 20, as expected. So, armed with the knowledge that a callback is somehow asynchronous I removed the sleep and put this instead:

doHeavyStuff(function() {
    res.end('Hello World');
});

with the function simply defined:

function doHeavyStuff(callback) {
    sleep(10000);
    callback();
}

that of course does not work... I have also tried to define an EventEmitter and register to it, but the main function of the Emitter has the sleep inside before emitting 'done', for example, so again everything will run block.

I am wondering here how other people wrote non-blocking code... for example the mongojs module, or the child_process.exec are non blocking, which means that somewhere down in the code either they fork a process on another thread and listen to its events. How can I replicate this in a metod that for example has a long process going?

Am I completely misunderstanding the nodejs paradigm? :/

Thanks!

Update: solution (sort of)

Thanks for the answer to Linus, indeed the only way is to spawn a child process, like for example another node script:

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"); });

The calculate.js can take its time to do what it needs and return. In this way, multiple requests will be run in parallel so to speak.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can't do that directly, without using some of the IO modules in node (such as fs or net). If you need to do a long-running computation, I suggest you do that in a child process (e.g. child_process.fork) or with a queue.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...