如何等待循环创buildstream保存之前完成?
我知道循环何时完成,
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); }); });
问题是:当我这样做时,数组arr是空的
book.images = arr
我需要等待for循环完成,但我怎么做?
我知道这个工程,因为我已经把一个console.log()
并正常工作
base64(writestream.name, function(response) { arr.push(response); });
可能最好在这里使用Promise.all
,但是你需要将每个“文件”包装在一个Promise中,并根据每个writeStream
完成时间或错误情况返回parsing:
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 }); });
这不涉及额外的依赖关系,但是您可以交替使用async.map
作为附加依赖项:
app.post('/api/books', upload.array('images'), function(req,res) { let book = req.body.book; var gfs = gridfsstream(conn.db); async.map( req.files, function(file,callback) { var writestream = gfs.createWriteStream({ filename: file.originalname }); fs.createReadStream('uploads/'+file.filename).pipe(writestream); writestream.on("error",callback); writestream.on("close",function() { base64(writestream.name, function(response) { callback(null,response); }); }); }, function(err,images) { if (err) throw err; book.images = images; Book.addBook(book,function(err,book) { if (err) throw err; // or whatever res.json(book) }); } ); });
所以他们看起来很相似,基本上他们也在做同样的事情。 在每种情况下,“循环”现在是一个.map()
,它将当前文件名作为参数传入,并返回转换响应的数组,在这种情况下,它是base64
函数的输出。 他们关键在于resolve
或callback
基本上是在事情发生的时候控制。
在使用Promise.all
的情况下, .map()
是数组上的基本JavaScript .map()
函数,它基本上返回一个“ Promise数组”,它们都实现了reject
和resolve
函数,然后由stream中的相应处理程序。
在这里,“Promises”全部执行并返回Promise.all
结果,并将输出数组传递给具有.then()
的块,然后传递给你的方法来更新/创build。
在async.map
示例中,它使用一个callback
参数,该参数再次提供给stream上的事件处理程序。 完全相同的方式,最后的块接收输出或错误,并可以再次传递给你的方法来坚持数据。
调用的实际执行有一些细微的差别,但两者实质上都是将我们“输出”输出完成的原理应用于提供“循环”的机制,以便我们知道何时“全部”完成。