Vòng lặp forEach trong lần thử của bạn không nhận dạng được quá trình hoàn tất gọi lại của findById ()
phương thức async trước lần lặp tiếp theo. Bạn cần sử dụng bất kỳ async
nào
các phương thức thư viện async.each
, async.whilst
hoặc async.until
tương đương với vòng lặp for và sẽ đợi cho đến khi lệnh gọi lại của async được gọi trước khi chuyển sang lần lặp tiếp theo (nói cách khác, vòng lặp for sẽ mang lại kết quả).
Ví dụ:
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);
});
Đối với toàn bộ hoạt động, bạn có thể sử dụng mã async.waterfall () >
cho phép mỗi hàm chuyển kết quả của nó cho hàm tiếp theo.
Hàm đầu tiên trong phương thức này tạo ra bài viết mới.
Hàm thứ hai sử dụng async.each ()
chức năng tiện ích để lặp qua danh sách nền tảng, thực hiện tác vụ không đồng bộ cho mỗi id để cập nhật nền tảng bằng cách sử dụng findByIdAndUpdate ()
và khi tất cả chúng hoàn tất, trả về kết quả của truy vấn cập nhật trong một biến đối tượng cho hàm tiếp theo.
Chức năng cuối cùng sẽ cập nhật bài viết mới được tạo với id nền tảng từ đường dẫn trước đó.
Giống như ví dụ sau:
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);
});