2017-07-01 1 views
1

J'ai un problème de savoir quand la boucle est terminée,Comment attendre une boucle pour créer des flux avant de les sauvegarder?

app.post('/api/books', upload.array('images'), function(req, res) { 
    let book = req.body.book; 
    let arr = []; 

    // GridFS get connection with DB 
    var gfs = gridfsstream(conn.db); 
    var writestream; 

    for (i = 0; i < req.files.length; i++) { 
     writestream = gfs.createWriteStream({ 
      filename: req.files[i].originalname 
     }); 
     fs.createReadStream('uploads/' + req.files[i].filename).pipe(writestream); 
     writestream.on("close", function(file) { 
      console.log(file.filename + "stored successfully into mongodb using gridfs"); 
     }); 
     writestream.on("error", function(file) { 
      console.log(file.filename + "not stored into mongodb using gridfs"); 
     }); 

     base64(writestream.name, function(response) { 
      arr.push(response); 
     }); 
    } 

    book.images = arr; 
    Book.addBook(book, function(err, book) { 
     if (err) { 
      throw err; 
     } 
     res.json(book); 
    }); 
}); 

Le problème est: L'arr tableau est vide quand je fais

book.images = arr 

Je dois attendre la boucle soit terminée, mais Comment puis je faire ça?

Je sais que cela fonctionne parce que je l'ai déjà mis un console.log() et fonctionne correctement

base64(writestream.name, function(response) { 
    arr.push(response); 
}); 

Répondre

1

probablement préférable d'utiliser Promise.all ici, mais vous devez envelopper chacun des « fichiers » dans une promesse et revenir Resoluée sur la base lorsque le writeStream dans chaque fin ou l'erreur:

app.post('/api/books', upload.array('images'), function(req,res) { 
    let book = req.body.book; 
    var gfs = gridfsstream(conn.db); 

    Promise.all(
    req.files.map(function(file) => { 
     return new Promise(function(resolve,reject) { 
     var writestream = gfs.createWriteStream({ 
      filename: file.originalname 
     }); 

     fs.createReadStream('uploads/'+file.filename).pipe(writestream); 

     writestream.on("error",reject); 
     writestream.on("close",function() { 
      base64(writestream.name, function(response) { 
      resolve(response); 
      }); 
     }); 

     }) 
    }) 
) 
    .then(function(images) { 
    book.images = images; 
    Book.addBook(book,function(err,book) { 
     if (err) throw err; // or whatever 
     res.json(book) 
    }); 
    }) 
    .catch(function(err) => { 
    // Deal with errors 
    }); 
}); 

Cela implique pas de dépendances supplémentaires, cependant vous pouvez utiliser alternativement async.map comme une dépendance supplémentaire:Donc ils ont l'air assez similaires, et fondamentalement ils font la même chose. Dans chaque cas, la "boucle" est maintenant un .map() qui passe le nom de fichier actuel comme argument et renvoie un tableau de la réponse transformée, qui est dans ce cas la sortie de votre fonction base64. La clé ici est que le resolve ou callback est fondamentalement dans le contrôle de quand les choses se produisent.

Dans le cas en utilisant Promise.all, la .map() est une fonction JavaScript .map() de base sur le tableau, qui est essentiellement de retour d'un « tableau de Promise » qui tous mettent en œuvre les fonctions reject et resolve qui sont ensuite appelés par les gestionnaires respectifs sur la courant.

Ici, les "Promises" s'exécutent tous et retournent les résultats dans le Promise.all et transmettent le tableau de sortie au bloc avec .then(), qui a le contenu et peut ensuite passer à votre méthode pour mettre à jour/créer comme peut être le cas. Par exemple, dans l'exemple async.map, cet argument utilise plutôt un argument callback qui est à nouveau fourni aux gestionnaires d'événements sur le flux. De la même manière, le bloc final reçoit la sortie ou l'erreur et peut à nouveau passer à votre méthode pour conserver les données. Il y a une légère différence dans l'exécution réelle des appels, mais les deux appliquent essentiellement le même principe que nous "signalons" la sortie a terminé au mécanisme fournissant la "boucle", de sorte que nous sachions quand "tous" ont terminé .

+0

Merci !!!! travaillé parfaitement !!! –