我如何等待循环中的回调更改变量,仍然使用异步性?
第二个例子是使用异步,在这种情况下我不知道如何将第二个参数sum
添加到wait
,以避免全局var sum
。称为wait(sum,value);
,返回值为sum
wait
是一个复杂函数的表示,我在我的实际问题中使用它,所以它不能被重写为“inline”-code并且必须保持“function”。
例1:
var _ = require('underscore');
var arr = [1,2,3,4,5,6,7];
var sum = 0;
function wait(item,callback) {
setTimeout(function() {
callback(item);
}, Math.ceil(Math.random()*1000));
}
var done = _.after(arr.length,function(value) {
console.log('sum ='+value);
})
_.each(arr,function(itm) {
wait(itm,function(value) {
console.log('waiting... '+value);
sum = sum + value;
})
// Please wait for the callback
console.log(itm);
done(sum);
});
例2:
function asyncExample2() {
var async = require('async');
var arr = [1,2,3,4,5,6,7];
function otherWait(item, callback) {
setTimeout(function() {
callback(item); // call this when you're done with whatever you're doing
}, Math.ceil(Math.random()*1000));
}
function wait(item, callback) {
setTimeout(function() {
otherWait(item,function() {
console.log(item);
});
callback(item);
}, Math.ceil(Math.random()*1000));
}
function done() { console.log("sum = "+sum);};
var sum = 0;
async.forEach(arr, wait, done);
}
所需电话:
sum = wait(sum,item)
答案 0 :(得分:4)
最简单的方法是将done
放入函数wait
。只有在执行完done
后才会调用callback
。
var arr = [1,2,3,4,5,6,7];
var sum = 0;
function wait(item,callback) {
setTimeout(function() {
callback(item);
done(sum);
}, Math.ceil(Math.random()*1000));
}
var done = _.after(arr.length,function(value) {
console.log('sum ='+value);
})
_.each(arr,function(itm) {
wait(itm,function(value) {
console.log('waiting... '+value);
sum = sum + value;
})
// Please wait for the callback
console.log(itm);
//done(sum);
});
输出:
答案 1 :(得分:2)
下划线完全同步,因此done(sum)
将在wait
执行完毕之前执行。
对于异步操作,请勿使用下划线。
像这样简单的事情应该做你想做的事情:
var sum = 0;
var waitNext = function(pos) {
wait(arr[pos], function(value)) {
if(pos < arr.length)
{
console.log('waiting... '+value);
sum += value;
waitNext(pos+1);
}
else
{
done(sum);
}
}
}
waitNext(0);
您当然可以避免使用waitNext
而只是修改wait
但如果wait
不是您的代码,这将有效。
不确定您是否想要sum += value
在if之前或之前,因为现在您可以通过调整if条件的顺序来删除不必要的waitNext
电话。
答案 2 :(得分:2)
你可以真正做一个没有全局变量的递归版本。
var arr = [1,2,3,4,5,6,7];
function wait(arr, max, callback, sum, done) {
var item = arr.shift();
setTimeout(function(){
if(item) {
sum[0] = callback(item, sum[0]);
sum[1]++;
}
else
sum[1] === max ? done(sum[0]) : wait(arr,max, callback, sum, done);
}, Math.random()*1000);
item && wait(arr, max,callback, sum, done);
}
function cb(item, acc) {
console.log('waiting....' + item);
return item + acc;
}
function done(sum) {
console.log(sum);
}
wait(arr, arr.length,cb, [0, 0], done);
输出
答案 3 :(得分:1)
我假设您正在使用setTimeout来实现 asynchronus 行为,而您可以使用像async这样的库,它可以更轻松地为您处理。
之前var async = require('async');
var arr = [1,2,3,4,5,6,7];
var sum = 0;
async.forEach(arr, function(item, cb){
sum = sum + item;
cb();
}, function(err){
console.log(sum);
});