1

I am still not understanding how asyncronous code works or is created in NodeJS. See below code and output.

Code:

var async = require('simple-asyncify');


function calc(){
    n1 = Math.round(Math.random() * (100 - 1) + 1);
    n2 = Math.round(Math.random() * (100 - 1) + 1);
    n3 = n1*n2;
    // console.log(n3);
    return n3;
}


function longRun(id)
{
    console.log("start long run: "+ id);

    for(i=0; i<100000000; i++){
        calc();
    }

    console.log("end long run: " + id);
}    

longRunAsync = async(longRun);


console.log("before");
longRunAsync(1, function(){});
longRunAsync(2, function(){});
longRunAsync(3, function(){});
console.log("after");

Output:

before
after
start long run: 1
end long run: 1
start long run: 2
end long run: 2
start long run: 3
end long run: 3

Without the line

longRunAsync = async(longRun);

And using the original function longRun vs longRunSync the output is :

before
start long run: 1
end long run: 1
start long run: 2
end long run: 2
start long run: 3
end long run: 3
after

So obviously something is running asynchronously but not the way I expected. It looks like it does all the synchronous code then swings back around and does the functions that are supposed to be asynchronous in a synchronous way.

Why is the output not like the below and how can I make it execute like this:

before
start long run: 1
start long run: 2
start long run: 3
after
end long run: 1
end long run: 2
end long run: 3

I think you get the idea, I want each call of longRunAsync to run well, asynchronously.

3
  • I don't know that library, but if you are starting out, I would suggest you go straight to promises - e.g. github.com/petkaantonov/bluebird Commented Feb 27, 2016 at 18:49
  • 1
    Your longRun function is synchronous, that's why it finishes it's job and then the second longRun is called. Commented Feb 27, 2016 at 18:57
  • I'd suggest you start by reading the doc for simple-asyncify and then ask a more specific question about why you're seeing some specific behavior. There is no magic bullet in simple-asyncify. It doesn't make a synchronous operation somehow run in the background. It just postpones running it until after the current event loop action finishes. AND, you must pass a callback to your asyncified function in order to know when its done or get its results. Read the asyncify doc please if you really intend to use that. Commented Feb 27, 2016 at 19:05

1 Answer 1

1

You're really not using that 'simple-asyncify' library correctly. You should be handling the callback returned by your wrapped function...

longRunAsync(1, function(){});

to get the assync behavior you want.

I guess this must be some sort of learning exercise since the the non wrapped version of the functions gives you pretty reasonable behavior. To get the output you want, you'd rewrite your longRunAsync function something like this (you need to return the id):

function longRun(id)
{
    console.log("start long run: "+ id);

    for(i=0; i<100000000; i++){
        calc();
    }

    return id
}   

and place it in the callback from the wrapped function:

console.log("before");
longRunAsync(1, function(err, id){
    console.log("end long run: " + id);});
longRunAsync(2, function(){ 
    console.log("end long run: " + id)});
longRunAsync(3, function(){
   console.log("end long run: " + id)\});
console.log("after");

That will probably give you what you want, though it's a bit non-determinsitic. Those longRunAsync aren't guarranteed to complete in any particular order. Also it's possible that any one of those might complete before

 console.log("after"); 

And so your output might look something like this:

before
start long run: 1
start long run: 2
start long run: 3
end long run: 1
after
end long run: 2
end long run: 3

If you want yout async functions to execute in some sort of order, you'll have to nest them (aka callback hell) or use something like the the https://github.com/caolan/async.

Here's how the nesting might look (not tested). But I can't figure out how to get that console.log('after') to print out where you want it.

console.log("before");
longRunAsync(1, function(err, id){
    console.log("end long run: " + id);
    longRunAsync(2, function(){ 
            console.log("end long run: " + id);
            longRunAsync(3, function(){
                    console.log("end long run: " + id)\});});});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.