一种了解何时所有回调都在javascript中完成的方法

时间:2014-05-26 12:54:59

标签: javascript node.js cheerio

我有很多对服务的调用,最后我想在服务的所有回调都返回时写入我的最终集合文件。 有没有办法确保所有回调都已完成?

for (id in idsCollection) {
    object.callService(id, function (res) {
        collection.push(res);
    });
}

filewriter.writetoFile("filename.json", JSon.Stringify(collection));

编辑:只是为了记录我使用cheerio和nodeJS。

8 个答案:

答案 0 :(得分:7)

创建一个数组。每次设置回调时,都会将某些内容推送到阵列上。每次回调运行时都会弹出一些东西。检查回调函数中的数组是否为空。如果它为空,则完成所有回调。

答案 1 :(得分:2)

你可以简单地计算它们。在你的情况下,你似乎已经知道将会有多少回调。

var remaining = idsCollection.length; // assuming array
for (id in idsCollection) {
    object.callService(id, function (res) {
        collection.push(res);
        remaining -= 1; // decrement by 1 per callback
        // here you can check if remaining === 0 (all done)
    });
}

答案 2 :(得分:2)

我通常使用node-async库来做这类事情。它可以很容易地完成您正在谈论的内容:

async.each(yourArray,
    function(element, next) { 
        // this callback gets called for each element in your array
        element.doSomething(function(returnValue){
            next(returnValue) // call next when you're done
        }
    }, function(err, returnValues) {
        // when all the elements in the array are processed, this is called
        if (err) return console.log(err);
        console.log(returnValues) // this is an array of the returnValues
    });
})

答案 3 :(得分:1)

如果您使用的是jQuery,则可以使用$.when

示例:

exmCall1 = $.getJson(..);
exmCall2 = $.getJson(..);

$.when(exmCall1, exmCall2).done(function (exmCall1Ret, exmCall2Ret) {
    //do stuff
});

您可以在此处阅读实际文档:http://api.jquery.com/jquery.when/

答案 4 :(得分:1)

jQuery.Deferred()对象可能就是你要找的东西。

如果您使用的是HTML5,则可以使用promises

以下是如何创建承诺

var promise = new Promise(function(resolve, reject) {
  // do a thing, possibly async, then…

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

以下是如何使用它们

promise.then(function(result) {
  console.log(result); // "Stuff worked!"
}, function(err) {
  console.log(err); // Error: "It broke"
});

查看this link了解详情

答案 5 :(得分:1)

你可以使用灵活的lib http://caolan.github.io/nimble/

灵活的并行例子

var _ = require('nimble');

_.parallel([
    function (callback) {
        setTimeout(function () {
            console.log('one');
            callback();
        }, 25);
    },
    function (callback) {
        setTimeout(function () {
            console.log('two');
            callback();
        }, 0);
    }
], function(){
    console.log('done')
});

输出

> two
> one
> done

答案 6 :(得分:1)

我在这里看到很多答案,但我希望这个解决方案仍然可以帮助某人。

为每个要熄灭的回调创建一个承诺:

function funcToLoop(arg){
    return new Promise((resolve, reject) => {
        try{
            funcWithCallback(arg, (cbArg) => {
                // do your stuff
                resolve(cbArg)
            });  
        } catch (e) {
            reject(e)
        }
    });
}

然后,您可以创建一个循环作为异步函数并在此处处理最终结果/状态/等:

async function mainLoop(array){

    let results = [];

    for (let arg of array){
        results.push(await funcToLoop(arg))
    }
    // handle results
}

...或者你可以有一个同步功能,收集承诺并处理它们:

function mainLoop(array){

    let promises = [];

    for (let arg of array){
        promises.push(funcToLoop(arg))
    }
    Promise.all(promises).then(()=>{
        // handle promises
    })
}

克劳迪奥

答案 7 :(得分:0)

或做一些硬编码:

    var running;
    for (id in idsCollection) {
        object.callService(id, function (res) {
            collection.push(res);
            running += 1;
        });
    }

    var loop = setInterval(function() {
    if(running >= idsCollection.length) {
        filewriter.writetoFile("filename.json", JSon.Stringify(collection));
        clearInterval(loop);
    }
    , 500);