一种知道何时在javascript中完成所有回调的方法

一种知道何时在javascript中完成所有回调的方法,javascript,node.js,cheerio,Javascript,Node.js,Cheerio,我有很多对服务的调用,在调用结束时,我想在服务的所有回调都返回后将我的最终集合写入一个文件。 有没有办法确保所有回调都已完成 for (id in idsCollection) { object.callService(id, function (res) { collection.push(res); }); } filewriter.writetoFile("filename.json", JSon.Stringify(collection)); 编辑:仅

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

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

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

编辑:仅针对我正在使用cheerio和nodeJS的记录。

如果您使用的是jQuery,您可以使用
$。当

例如:

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

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

您可以在此处阅读实际文档:

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

对象可能就是您要查找的对象

或者,如果您正在使用HTML5,您可以使用
承诺

下面是如何创造承诺

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

查看更多信息

你可以简单地数一数。在您的情况下,您似乎已经知道将有多少回调

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)
    });
}
或者做一些硬编码:

    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);
您可以使用灵活的lib

敏捷并行示例 输出

> two
> one
> done
我通常使用图书馆来做这类事情。它可以让您轻松地完成所说的内容:

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

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

为每个回调创建一个承诺,使其失效:

function funcToLoop(arg){
    return new Promise((resolve, reject) => {
        try{
            funcWithCallback(arg, (cbArg) => {
                // do your stuff
                resolve(cbArg)
            });  
        } catch (e) {
            reject(e)
        }
    });
}
然后,您可以创建一个作为异步函数的循环,并在此处处理最终结果/状态/etc:

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

Claudio

您是否在使用jQuery?简单地说,在每次回调完成时减少一个全局_总数。在每次回调完成时调用check()函数,检查全局_total是否为0。如果为0,请执行您的特殊设置task@georg我在用cheerio和NodeJSW为什么不增加/减少计数器?你也可以这样做。将相关对象放在数组中可以为您提供更多检查它们的选项。这正是我想听到的:D+1这听起来是一个不错的解决方案,但是节点异步呢?这似乎是一个更干净的解决方案。好吧,这就是NodeAsync(本质上)所做的。这只是一个答案,而不是一个产品推荐。不要启动一个循环,每秒检查两次以查看回调是否完成。检查回调本身的条件。@Cerbrus
object.callWebservice
可能正在使用jquery。不管怎样,这个答案可能会帮助一些人通过谷歌遇到这个问题。谢谢,伙计,但是为了记录在案,我在nodejs中使用服务器端Javascript,还有一些cheerio。我需要在parralele中启动的并行函数的数量取决于运行时:)我不能像那样硬编码每个调用。正如你所看到的,第一个函数参数是数组。将任意多的函数推入阵列。
function mainLoop(array){

    let promises = [];

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