Confusion about CPU intensive code in Node.js

2019-03-09 22:22发布

问题:

A question regarding "everything runs in parallel except your code" from someone new to Node.js. This is an obviously artificial example, but let's say I want to create a math library containing a function factorize() which behaves as follows:

var http = require('http');
http.createServer(function (req, res) {
  myMath.factorize(some_big_number,function(factors) {
    res.writeHead(200, {'Content-Type': 'application/json'});
    res.end(JSON.stringify(factors));
  }
}).listen(8000);

How can this be written so that it will "run in parallel"?

I've been looking at the parsing code from this library as an example that might take some processing time. Is the body of the code considered to be "your code", or does this "run in parallel"?

If not: What do I need to do when writing factorize() so that it is also non-blocking/behaves like a client? Is using EventEmitter sufficient?

If so: Is my best option still to use child processes as suggested in this question?

Apologies in advance for any lack of clarity.

回答1:

Actually you can't run it "parallel" (unless you use a workers module) as JavaScript in node.js is executed in single thread but you can split your single thread into smaller pieces. For example with process.nextTick, so when the CPU is executing the code as smaller chunks instead of one long running code, it has small breaks to run other things as well.

myLongRunningCode(callback){
    do_a_piece_of_the_work();
    if(ready){
        callback();
    }else{
        // give the CPU a small break to do other things
        process.nextTick(function(){
            // continue working
            myLongRunningCode(callback);
        });
    }
}


回答2:

To write non blocking code you have to do message passing.

To do message passing you have to open a stream and pass messages through it. This involves talking to some other process or talking to a sub process.

You can create child processes to do heavy lifting for you in node or you can create a tcp/web service to do heavy lifting for you. Just get node to pass messages to them and then send data down your response when the external processes have done the heavy lifting.



回答3:

all your JS code can NOT run in parallel. There are never multiple functions executed at the same time. CPU intensive code would make your program unable to do something else until this code ends.

I recommend you to split your code with setTimeout or do your job in a separate process. But this must be REALLY intensive code ;)