Loop forEach dalam upaya Anda tidak mengenali penyelesaian panggilan balik dari findById()
metode async sebelum iterasi berikutnya. Anda perlu menggunakan salah satu dari async
metode perpustakaan async.each
, async.whilst
, atau async.until
yang setara dengan perulangan for, dan akan menunggu hingga panggilan balik async dipanggil sebelum melanjutkan ke iterasi berikutnya (dengan kata lain, perulangan for yang akan menghasilkan).
Misalnya:
var platform_docs = [];
async.each(platforms, function(id, callback) {
Platform.findById(id, function(err, platform) {
if (platform)
platform_docs.push(platform);
callback(err);
});
}, function(err) {
// code to run on completion or err
console.log(platform_docs);
});
Untuk keseluruhan operasi, Anda dapat menggunakan async.waterfall()
metode yang memungkinkan setiap fungsi meneruskan hasilnya ke fungsi berikutnya.
Fungsi pertama dalam metode membuat artikel baru.
Fungsi kedua menggunakan async.each()
fungsi utilitas untuk mengulangi daftar platform, melakukan tugas asinkron untuk setiap id untuk memperbarui platform menggunakan findByIdAndUpdate()
, dan setelah semuanya selesai, kembalikan hasil kueri pembaruan dalam variabel objek ke fungsi berikutnya.
Fungsi terakhir akan memperbarui artikel yang baru dibuat dengan id platform dari pipeline sebelumnya.
Sesuatu seperti contoh berikut:
var newArticle = {},
platforms = req.body.platforms,
date = req.body.date,
split = date.split("/");
newArticle.title = req.body.title;
newArticle.description = req.body.description;
newArticle.date = split[2]+'/'+split[0]+'/'+split[2];
newArticle.link = req.body.link;
newArticle.body = req.body.body;
console.log(platforms);
async.waterfall([
// Create the article
function(callback) {
var article = new Article(newArticle);
article.save(function(err, article){
if (err) return callback(err);
callback(null, article);
});
},
// Query and update the platforms
function(articleData, callback) {
var platform_ids = [];
async.each(platforms, function(id, callback) {
Platform.findByIdAndUpdate(id,
{ "$push": { "articles": articleData._id } },
{ "new": true },
function(err, platform) {
if (platform)
platform_ids.push(platform._id);
callback(err);
}
);
}, function(err) {
// code to run on completion or err
if (err) return callback(err);
console.log(platform_ids);
callback(null, {
"article": articleData,
"platform_ids": platform_ids
});
});
},
// Update the article
function(obj, callback) {
var article = obj.article;
obj.platform_ids.forEach(function(id){ article.platforms.push(id); });
article.save(function(err, article){
if (err) return callback(err);
callback(null, article);
});
}
], function(err, result) {
/*
This function gets called after the above tasks
have called their "task callbacks"
*/
if (err) return next(err);
console.log(result);
res.redirect('articles/' + result._id);
});