2014-07-04 24 views
0

我想执行一个for-loop结构内的异步方法,然后显示结果。我相信问题是在cryto.randomBytes方法调用回调之前,for-loop增量。我将如何正确执行这个for循环?如何正确执行for循环内的异步方法?

var crypto = require('crypto'); 
var nimble = require('nimble'); 

var codes = []; 

nimble.series([ 
function(callback){ 

    for(var i = 0; i < 100;i++){ 

     crypto.randomBytes(64, function(ex, buf) { 
      if (ex) throw ex; 
      codes[i] = buf.toString('hex'); 
     }); 

    } 

    callback(); 

}, 
function(callback){ 

    for(var i = 0; i < codes.length;i++){ 
     console.log("Ticket " + i + ":" + codes[i]); 
    } 

    callback(); 

}]); 

回答

2

是的,你说得对,循环在调用回调之前完成。您可以使用匿名函数来创建一个范围,其中每个迭代都获取自己的变量副本。

而且,你会调用回调后的最后一个值已经被添加到结果,在循环之后没有:

function(callback){ 

    var cnt = 0; 
    for(var i = 0; i < 100;i++){ 
    (function(i){ 
     crypto.randomBytes(64, function(ex, buf) { 
      if (ex) throw ex; 
      codes[i] = buf.toString('hex'); 
      if (++cnt == 100) { 
      callback(); 
      } 
     }); 
    })(i); 
    } 

} 
+0

很多不必要的关闭在这里创建。 – mscdex

+0

@mscdex:这可能可以简化,因为在这种特殊情况下,这些值是随机的,所以它们在数组中的最终顺序应该没有关系。除非不同的数字需要不同的时间才能生成,所以它实际上引入了随机数的可预测性,在这种情况下,它将大大降低随机生成器的强度。 – Guffa

+0

后者中的任何一个与创建闭包有什么关系? – mscdex

2

相反的:

function(callback){ 

    for(var i = 0; i < 100;i++){ 

     crypto.randomBytes(64, function(ex, buf) { 
      if (ex) throw ex; 
      codes[i] = buf.toString('hex'); 
     }); 

    } 

    callback(); 

}, 

你可以尝试这样的:

function(callback){ 

    for(var i = 0, len = 100; i < len; i++){ 

     crypto.randomBytes(64, function(ex, buf) { 
      if (ex) throw ex; 
      codes.push(buf.toString('hex')); 
      if (codes.length === len) 
       callback(); 
     }); 

    } 

}, 
1

使用具有递归性的IIFE应该可以工作:

var crypto = require('crypto'); 
var nimble = require('nimble'); 

var codes = []; 

nimble.series([ 

function (callback) { 

    // Using an IIFE 
    (function recursive(index) { 

     if (index < 100) { // i < 100 
      crypto.randomBytes(64, function (ex, buf) { 
       if (ex) throw ex; 
       codes[index] = buf.toString('hex'); 
       recursive(index + 1); 
      }); 
     } else callback(); 

    })(0); // i = 0 

}, 

function (callback) { 

    for (var i = 0; i < codes.length; i++) { 
     console.log("Ticket " + i + ":" + codes[i]); 
    } 

    callback(); 

}]);