0

I have some trouble managing the flow control in node.js. Here is my problem:

I have an array of objects, and I want to do something with every object (for example write it to file or send somewhere via network...). I want to be sure that every object is processed and after that i wanna continue with some other function. In this example processObj() function is iterating through every object and write that object to file. Where should I put callback call to be sure that callback function of processObj() will be executed after all objects are written to the file?

//Array of n objects...
var objArray=[{},{},{},{}];

//process every Object, for example write object to file...

function proccessObj(obj,callback){
    var myObj = obj;
    for(var i=0;i<myObj.length;i++){
        //process single object, for example:
        ws.appendFile('file.txt',myObj[i],function(){
            //callback
        })
    }
    callback() // <-- If i put callback here it will be executed before callbacks of  ws.apendFile

}

//execute function
processObj(objArray,function{

    //Do something after  all objects in array are saved to file...
});
2

3 Answers 3

1

If this function doesn't run multiple times at the same time, I suggest you do this :

function proccessObj(obj,callback){
    var myObj = obj;
    for(var i=0;i<myObj.length;i++){
        //process single object, for example:
        ws.appendFile('file.txt',myObj[i],function(){
            //callback
            if(!--i) callback();
        })
    }
}

Inside the appendFile callback, the variable i will be equal to myObj.length. Tehn, when the callback is done, it will decrease the variable i by one and once it reach 0, the callback will proc.

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

1 Comment

This is dangerous. If ws.appendFile runs synchronously at any point (which could be reasonable behavior if, for example, myObj[i] was an empty string) you will manipulate i partway through the loop. Just use an extra variable.
0

Use a counter.

function proccessObj(obj,callback){
    var myObj = obj;
    var pending = myObj.length;  // keep track of done items
    for(var i=0;i<myObj.length;i++){
        //process single object, for example:
        ws.appendFile('file.txt',myObj[i],function(){ 
            pending--;
            if (pending == 0) {
                callback(); // This callback will be executed after all the items are done
            }
        })
    }

}

Comments

0

Thanks guys! It seems that a asynchronous semaphore is a good solution. But again I have to ask if this is good way of implementing a very simple semaphore, and is it a good solution for my problem:

function processObj(obj,callback){
        var semaphore = 0;
        var myObj = obj;
        for(var i=0;i<myObj.length;i++){
            //process single object, for example:
            semaphore++;
            ws.appendFile('file.txt',myObj[i],function(){
                semaphore--;
                if(semaphore===0){
                    callback();
                }
            })
        }
}

It works good in my case, and it doesn't require any modules, but I'm not sure is it a good way for solving this problem.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.