for call with callbacks

时间:2014-03-04 13:28:15

标签: javascript node.js asynchronous

我在node.js中管理流控制时遇到了一些问题。这是我的问题:

我有一个对象数组,我想对每个对象做一些事情(例如将其写入文件或通过网络发送到某处......)。我想确保每个对象都被处理,然后我想继续其他一些功能。在此示例中,processObj()函数是 遍历每个对象并将该对象写入文件。应该在哪里放置回调调用以确保在将所有对象写入文件后执行processObj()的回调函数?

//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...
});

3 个答案:

答案 0 :(得分:1)

如果此功能没有同时运行多次,我建议你这样做:

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();
        })
    }
}

appendFile回调中,变量i将等于myObj.length。 Tehn,当回调完成时,它会将变量i减少一个,一旦它达到0,回调就会触发。

答案 1 :(得分:0)

使用计数器。

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
            }
        })
    }

}

答案 2 :(得分:0)

谢谢你们! 似乎异步信号量是一个很好的解决方案。但我还要问,这是否是实现一个非常简单的信号量的好方法,这对我的问题是一个很好的解决方案:

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();
                }
            })
        }
}

它在我的情况下效果很好,它不需要任何模块,但我不确定它是解决这个问题的好方法。