我想总结一下异步生成的数据(在node.js中)。 你会如何以线程安全的方式做到这一点?
例如,
function test(){
var accumulator = 0;
for(int i= 0; i<100; i++){
// non blocking function producing value
getasyncdata(i, function(value){
// this is spread over 3 lines to simulate non atomic operation.
tmp = accumulator;
tmp = tmp + value;
accumulator = tmp;
});
}
console.log(accumulator);
}
我看到getdata回调的方式将在并行中被调用100次...并且由于回调不是原子的(或者是?),因此累积器不会是100个值的总和。 / p>
您怎么看?
答案 0 :(得分:2)
您可以使用检查任何作业是否正在运行的函数,然后在完成后打印。例如:
function test(){
var accumulator = 0, pendingOps = 0;
for(int i= 0; i<100; i++){
// non blocking function producing value
pendingOps++;
getasyncdata(i, function(value){
// this is spread over 3 lines to simulate non atomic operation.
tmp = accumulator;
tmp = tmp + value;
accumulator = tmp;
printIfFinished();
});
function printIfFinished() {
pendingOps--;
if(pendingOps) == 0 {
console.log(accumulator);
}
}
}
}
有很多控制流程库可以帮助你做到这一点,其中两个比较流行的是:
答案 1 :(得分:-1)
虽然实际的异步操作可能同时发生(在单独的线程中),但由于Nodes事件循环是单线程的,因此在给定时间只会触发一个回调。因此,保证accumulator
确实是所有值的总和。
至于您的示例代码,console.log(accumulator)
将为零,因为getasyncdata
是非阻塞的,因此console.log将在异步调用完成之前执行。如果您希望记录最终累积的数据,您可以这样实现:
function test() {
var accumulator = 0;
var counter = 0;
for (int i = 0; i < 100; i++) {
// non blocking function producing value
getasyncdata(i, function (value) {
// this is spread over 3 lines to simulate non atomic operation.
tmp = accumulator;
tmp = tmp + value;
accumulator = tmp;
counter++;
if (counter == 100) {
console.log(accumulator);
}
});
}
}