2017-06-20 1 views
1

Je suis relativement nouveau dans Node.js et je suis toujours en train de faire le tour des callbacks et de la nature asynchrone de Node.js. J'ai rencontré un problème que je ne peux pas comprendre; J'ai minutieusement cherché le débordement et lu les documents de support, mais je n'arrive toujours pas à le faire fonctionner. Essentiellement, le problème est que j'ai un tableau d'objets et que je voudrais appliquer un certain nombre d'opérations asynchrones en séquence à chaque objet. J'ai regardé Async.js et essayé diverses structures de rappel, mais mon compilateur ne cesse de me crier dessus.Résultat inattendu des opérations asynchrones mutiples sur chaque objet dans le tableau

Ma version la plus récente du code est:

function processObjects(objects){ 

    console.log(objects); 

    async.forEachOf(objects, function(object, key, callback){ 

     var imageProfile; 
     var files = {}; 

     function readFile(callback){ 
      fm.mdfil("templates/no_object.jpg", function(result) { // Read metadata from no_object.jpg template 
       console.log("check1"); 
       files['name'] = object + "_" + timestamp + ".jpg"; // file.name = object.id + timestamp 
       files['type'] = ".jpg"; 
       files['size'] = result.size; 
       callback(); 
      }); 
     } 

     function updateFileProfileAgain(result, callback){ 
      console.log("check2"); 
      var obj = []; 
      obj.push(object); 
      f.insF(req.user._id, files.name, "", "", files.type, files.size, "", "", "", timestamp, obj, function(result){ // Add record of the image to the Files Collection 
       callback(null, result); 
      }); 
     } 

     function updateImageRef(result, callback){ 
      console.log("check3"); 
      o.updSO(object, "imageRef", imageProfile.insertedId, function(result){ 
       callback(null, result); 
      }); 
     } 

     function updateObjectImage(result, callback){ 
      console.log("check4"); 
      o.updSO(object, "objectImg", files.name, function(result){ 
       callback(null, result); 
      }); 
      callback(); 
     } 

     readFile(function(callback){ 
      updateFileProfileAgain(function(result, callback){ 
       updateObjectImage(function(result, callback){ 
        updateImageRef(function(result, callback){ 
         console.log(result); 
        }); 
       }); 
      }); 
     }); 

     readFile(); 
    }, 
    function(err, result){ 
     console.log("done"); 
    }); 
} 

Timestamp est une variable globale. Objects est un tableau avec des ID uniques. Essentiellement je veux analyser tous ces identifiants uniques pour leur donner leur propre image (dans la fonction readFile), ajouter un enregistrement de cette image à une collection séparée (updateFileProfileAgain), ajouter une référence de l'enregistrement inséré à l'enregistrement de l'objet (updateImageRef) et éventuellement ajouter une chaîne de l'enregistrement d'image au champ objectImg par objet (updateObjectImage).

La sortie de ce code a varié de callbacks indéfinis (en tant que fonctions) et de résultats indéfinis. Dans certains cas, j'ai obtenu le résultat sur le client, qui afficherait alors un enregistrement mis à jour pour un objet, mais pas pour l'autre (comme si la variable fichiers ne se mettait pas à jour ou la dernière valeur connue), comme ceci:

  • Object [0]: imageRef: "594912a794c9dc8488292025"
  • Object [1]: imageRef: "";

Et même pour les champs objectImg etc.

Toute aide serait très apprécié!

Répondre

0

Vous ne passez pas le résultat de chaque fonction à la suivante.

En outre, les rappels peuvent être un mal de tête. Je vous recommande d'utiliser Promise chaining.

Objects.forEach(function (object) { 
    readFile(object) 
    .then(function(file) { return updateFileProfileAgain(file) }) 
    .then(function(result) { return updateObjectImage(result) }) 
    .then(function(image) { return updateImageRef(image) }); 
}); 

Avec ES6

Objects.forEach((object) => { 
    readFile(object) 
    .then(file => updateFileProfileAgain(file)) 
    .then(result => updateObjectImage(result)) 
    .then(image => updateImageRef(image)); 
}); 
+0

Salut Matías, merci pour votre réponse. J'ai essayé d'implémenter des promesses, mais ma console me dit qu'elle ne peut pas lire la propriété de 'alors'. Est-ce que je manque quelque chose d'évident ici? –