2

Supposing we have a script that will execute a certain task for each row in an array.

function execute(err, array){
    loop(array, function(err,object){
         console.log(object)
         //do a certain task when it's finished get into the next object successively.
    });
}

function loop(array,callback){
    array.forEach(function(object){
         callback(null, object);
    });
}

function array(callback){
     callback(null, [1, 2, 3, 4, 5]);
}

setTimeout(function(){
    array(execute); 
}, 6000);

Questions:

  • How to get into the next loop only after finishing the task?
  • Is my function considered asynchronous ?

4 Answers 4

2

Try this:

function execute(err, array) {
    loop(array, function(err, object, next) {
         console.log(object);
         next(); // this will call recur inside loop function
    }, function() {
         console.log('All done');
    });
}

function loop(array, callback, finish) {
    var copy = array.slice();
    (function recur() {
        var item = copy.shift();
        if (typeof item !== 'undefined') {
            callback(null, item, recur);
        } else if (typeof finish == 'function') { 
            finish();
        }
    })();
}

No, your function is not asynchronous, but you call it asynchronously using setTimeout.

EDIT: changed if check

typeof item !== 'undefined'

so it will work when array contain falsy values like 0 or null.

Sign up to request clarification or add additional context in comments.

7 Comments

How to verify this as the output is almost instant?
@AlessandroGenovese you can call next() in setTimeout
Perfect, is using the synchronous method this answer suggested: stackoverflow.com/questions/32159018/… will work? instead of just using settimeout?
@AlessandroGenovese don't know.
@AlessandroGenovese you do this in callback, recur is only for looping over array.
|
2

You can do something like this to iterate over your array :

var myarray = [1,2,3,4,5];
next(myarray, 0);

function next(array, idx) {
    if (idx !== array.length) {
        // do something
        console.log(array[idx]);

        // run other functions with callback
        another_fct(array[idx], function() {
            next(array, idx + 1); // then the next loop
        });

        // or run directly the next loop
        next(array, idx + 1);
     } else {
        // the entire array has been proceed
        console.log('an array of '+array.length+' number of elements have been proceed');
    }
}

function another_fct(array_element, callback) {
    // do something with array_element
    console.log('value : '+array_element);
    callback(); // run the next loop after processing
}

This method will perform your array elements synchronously.

1 Comment

I think you meant next(myarray, idx + 1) ?
0

async provides async.series and other helpers for this purpose.

Comments

0

You can wrap your head around it better if you refactor the code and remove any redundant anonymous functions. The case is, that passing an anonymous function as an argument to another function not yet make the function asynchronous. You read more a more in depth explanation in "Does taking a callback make a function asynchronous?".

From the refactored version,

setTimeout(function() {
    [1, 2, 3, 4, 5].forEach(function(object) {
        console.log(object)
        //do a certain task when it's...
    });
}, 6000);

it can be seen that forEach is called for the array. The forEach method executes provided function once per array element and does it synchronously.

So, to answer your question:

  1. yes, it calls the next item only after finishing previous (but if doing anything asynchronous, see below)
  2. this is not considered asynchronous since it doesn't perform any asynchronous operations (not considering the outer setTimeout)

However, if you choose to start an asynchronous operation in the forEach function, then things change considerably. The result is that all operations are in-progress at the same time. This is potentially a hazardous operation resource-wise. There are libraries such as async for handling this use case gracefully.

(Btw, good use of Node.js errbacks, where first function argument reserved for passing potential error.)

2 Comments

Had a misunderstanding of asynchronous and synchronous operations, I'm getting more into it atm. and yes I'm trying to make the code clean as much as I can using callbacks for easy modifications in the future, however could you please why using settimeout on the function makes it asynchronous?
This is tricky, and has a bit of a learning curve for sure. So asynchronous operation is something that leverages the host system and causes the callback function to be called at a later time instead of calling it directly (=synchronously). The setTimeout is an asynchronous function - it takes a callback and a millisecond value and fires the callback at a later time after the timeout has passed. By the way, Node.js progresses other things during the waiting time making if very efficient.

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.