2014-07-04 2 views
0

J'essaie d'exécuter une méthode asynchrone dans une construction for-loop, puis d'afficher le résultat. Je crois que le problème est que les incréments de la boucle for avant la méthode cryto.randomBytes appelle le rappel. Comment pourrais-je correctement exécuter cette boucle for?Comment exécuter correctement une méthode asynchrone dans une boucle 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(); 

}]); 

Répondre

2

Oui, vous avez raison de dire que la boucle est terminée avant l'appel des rappels. Vous pouvez utiliser une fonction anonyme pour créer une portée dans laquelle chaque itération obtient sa propre copie de la variable.

En outre, vous appelez le rappel après la dernière valeur a été ajoutée au résultat, et non après la boucle:

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

Beaucoup de fermetures inutiles sont créées ici. – mscdex

+0

@mscdex: Cela pourrait peut-être être simplifié car, dans ce cas particulier, les valeurs sont aléatoires, donc peu importe l'ordre dans lequel elles se retrouvent dans le tableau. À moins que des nombres différents prennent un temps différent à produire, de sorte qu'il introduit réellement la prévisibilité aux nombres aléatoires, auquel cas cela réduirait fortement la force du générateur aléatoire. – Guffa

+0

Qu'est-ce que l'un de ces derniers a à voir avec la création de fermetures? – mscdex

2

Au lieu de:

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(); 

}, 

Vous pouvez essayer quelque chose comme:

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

l'utilisation d'un récursivité avec Ia vie, devrait fonctionner:

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(); 

}]); 
Questions connexes