如何在for循环中正确执行异步方法?

时间:2014-07-04 19:50:09

标签: javascript node.js

我试图在for循环结构中执行异步方法,然后显示结果。我认为问题是在cryto.randomBytes方法调用回调之前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();

}]);

3 个答案:

答案 0 :(得分: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);
  }

}

答案 1 :(得分: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();
         });

     }

},

答案 2 :(得分: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();

}]);