De forEach-lus in uw poging herkent de callback-voltooiing van de findById()
niet asynchrone methode voor de volgende iteratie. U moet een van de async
gebruiken
bibliotheekmethoden async.each
, async.terwijl
, of async.tot
die equivalent zijn aan een for-lus, en zal wachten tot de callback van async wordt aangeroepen alvorens door te gaan naar de volgende iteratie (met andere woorden, een for-lus die zal opleveren).
Bijvoorbeeld:
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);
});
Voor de hele operatie zou je de async.waterfall()
methode waarmee elke functie zijn resultaten kan doorgeven aan de volgende functie.
De eerste functie in de methode maakt het nieuwe artikel aan.
De tweede functie gebruikt de async.each()
hulpprogramma om de lijst met platforms te doorlopen, voer een asynchrone taak uit voor elke id om het platform bij te werken met findByIdAndUpdate()
, en wanneer ze allemaal klaar zijn, retourneert u de resultaten van de update-query in een objectvariabele naar de volgende functie.
De laatste functie werkt het nieuw gemaakte artikel bij met de platform-ID's uit de vorige pijplijn.
Iets als het volgende voorbeeld:
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);
});