Reputation: 7362
In the javascript program below (Euler problem 5) I am practicing writing asynchronous / non blocking function. The program is trying to find the smallest number evenly divisible by numbers 1-10. 2520 is the first smallest and that is where the program should stop.
I set up the program so that if the functions run together, then the second checkNum should be done first and print the second one first, then the first one, but that is not happening?
How can I get the function to run at the same time, instead of one after another? I am expecting the callback from the second checkNum function I call to be called first (since it starts closer to the answer), then the first, but that is not what happens. Thanks so much!
var divides = function(a, b) {
return b % a == 0;
};
function checkNum(counter, callback) {
var noRemainder = 0;
var forward = true;
while (forward)
{
for (var i = 1; i <= 10; i++) {
if (divides(i, counter))
{ noRemainder++; }
}
if (noRemainder == 10) {
console.log(counter);
forward = false;
callback(counter);
} else {
console.log(noRemainder);
noRemainder = 0;
counter++;
console.log(counter);
}
}
}
checkNum(1, function(counter) {
setTimeout(function(){
console.log("The counter is: " + counter)},3000)
}
);
checkNum(2500, function(counter) {
setTimeout(function(){
console.log("The counter2 is: " + counter) },3000)
}
);
Upvotes: 0
Views: 247
Reputation: 144912
Because checkNum
is a purely CPU-bound function – that is, the only thing it does is perform computation in a tight loop – there is no reason to make it asynchronous. The function is by definition synchronous; control does not return to the caller until computations complete. Consider the following async style:
checkNum(n, function(err, result) {
console.log(result);
});
console.log('Next line');
...and synchronous style:
console.log( checkNum(n) );
console.log('Next line');
In both cases, the result of checkNum
will be printed before "Next line". Even in the async style, control is not returned until after checkNum
invokes its callback and the callback completes. (Compare this to truly asynchronous functions where "Next line" would get printed before the callback gets a result.)
The real magic of node comes from the fact that most expensive operations (like I/O) are performed on a separate thread by native code, and when they're done, they invoke a JavaScript callback on the main thread. As a result, very little time is spent executing JavaScript, so your application performs exceptionally well.
However, if you find yourself writing expensive loops and calculations like this in JavaScript, you have to remember that you'll be blocking everything for the amount of time your function runs. Things happening on other threads will queue up and your application code will not have a chance to do anything until the expensive function returns.
There are several ways to work around this limitation, in order of performance:
nextTick
to start the processing on each chunk. This allows any queued events to process between chunks.fork
to do this since it comes with built-in IPC. Here's an example fibonacci calculator. Keep in mind this does come with overhead: it takes ~30ms and at least 10 MB of RAM to start a new node process.Upvotes: 2
Reputation: 6252
You may want to give the core cluster module a try which will allow you to run a node process per core. It may work with a single core, but multiple cores is highly recommended for this approach.
Another thing to check out is the async module with the parallel control flow, though this is still applicable to the notion of the single thread.
Upvotes: 0
Reputation: 10184
You cannot have the functions run truly simultaneously, as if you had multiple threads running in parallel. This is because Javascript is single threaded, not multithreaded. The best you really get is "sorta kinda" parallel operation that really, in practice, isn't parallel.
Upvotes: 0