一种知道何时在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
})
}