ForEach-løkken i dit forsøg genkender ikke tilbagekaldsfuldførelsen af findById()
asynkroniseringsmetode før næste iteration. Du skal bruge nogen af async
biblioteksmetoder async.each
, async.whilst
, eller async.until
som svarer til en for-løkke, og vil vente, indtil async's tilbagekald kaldes, før de går videre til næste iteration (med andre ord, en for-løkke, der vil give).
For eksempel:
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);
});
Til hele operationen kan du bruge async.waterfall()
metode, som gør det muligt for hver funktion at videregive sine resultater til den næste funktion.
Den første funktion i metoden opretter den nye artikel.
Den anden funktion bruger async.each()
hjælpefunktion til at iterere over platformslisten, udfør en asynkron opgave for hvert id for at opdatere platformen ved hjælp af findByIdAndUpdate()
, og når de alle er færdige returnerer resultaterne af opdateringsforespørgslen i en objektvariabel til den næste funktion.
Den sidste funktion vil opdatere den nyoprettede artikel med platform-id'erne fra den forrige pipeline.
Noget i stil med følgende eksempel:
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);
});