1

Here is some code I am trying :

startTask();

function startTask(){
    console.log('startTask enter');
    startLongTask(1, function(){
        console.log('long task complete');
    });
    console.log('startTask exit');
}

function startLongTask(i, callback) {
    while (i++ < 10000){
        console.log(i);
    }
    callback();
}

And here is the output (omitting the large series on numbers):

startTask enter
2
3
4
5
6
7
8
9
10
long task complete
startTask exit

As evident, if I have a long running operation, it's synchronous. It's like having startLongTask inline in startTask. How do I fix this callback to be non-blocking. The output I expect is :

startTask enter
startTask exit
2
3
4
5
6
7
8
9
10
long task complete
lazyloader
  • 29
  • 4
  • 1
    http://stackoverflow.com/questions/18613023/how-to-create-threads-in-nodejs – Arun P Johny Mar 25 '15 at 03:14
  • I don't know if node has another way but the only way to do asynchronous processing in the browser other than HTTP requests is by using web workers [MDN Article](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) – HJ05 Mar 25 '15 at 03:15
  • I am a JS beginner, so please help me understand how 'fs' module (or any other nodejs module) supports similar features ? They dont use webworkers, but they seem to achieve the goal. – lazyloader Mar 25 '15 at 03:20
  • What about something like an [asynchronous loop](http://stackoverflow.com/questions/4288759/asynchronous-for-cycle-in-javascript)? – incutonez Mar 25 '15 at 03:23
  • possible duplicate of [Make a function run in parallel](http://stackoverflow.com/q/24835556/1048572) (it asks about promises, but the answers are not specific to that) – Bergi Mar 25 '15 at 03:24

2 Answers2

2

Javascript-only code does not have the ability to create new asynchronous operations in pure JS because the V8 interpreter in node.js does not give you full-fledged threads.

Libraries such as the fs module in node.js get their async behavior from native operations (outside of the JS/V8 world) and they interface to the JS engine with an async interface.

That said, there are ways you can run operations in the background in node.js by using some non-JS code. You can start another process, you can use a variety of add-on modules that support other threads of execution, etc... All of these will go outside of pure node.js Javascript in order to offer an async interface.

If your task can be broken into short chunks, you can also simulate an asynchronous operation by doing small amounts of work on successive timers (this is a common work-around in the browser too).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Of course, timers go outside of pure javascript as well :-) – Bergi Mar 25 '15 at 04:07
  • Um, it's from the [`Timers` add-on](http://www.w3.org/TR/html5/webappapis.html#timers)? – Bergi Mar 25 '15 at 04:20
  • @Bergi - why are you pressing this point? You know exactly what my answer means. It appears you're just trying to make a technical argument that is irrelevant to the point here (and the argument is quite a stretch too since `setTimeout()` is built into node.js with no `require()` needed to load it). – jfriend00 Mar 25 '15 at 04:39
  • Sorry, I didn't want to argument; it's just a minor addition to your good answer - you've got my +1 already. – Bergi Mar 25 '15 at 12:15
0

You can use a timeout function with 0 milliseconds delay. Any functions in the timeout will be pushed to the end of the execution thread. e.g.

startTask();

function startTask(){
    console.log('startTask enter');
    setTimeout(function(){
        startLongTask(1, function(){
            console.log('long task complete');
        })
    }, 0);
    console.log('startTask exit');
}

function startLongTask(i, callback) {
    while (i++ < 100){
        console.log(i);
    }
    callback();
}
NoGray
  • 1,149
  • 7
  • 9