我有一系列课程[course1,course2,...,courseN]。每个课程都有一个Hero UUID,它匹配另一个集合中对象的UUID。
// This is actually another db query but imagine it's an array
var courses = [{
"courseName": "Sample course name 1",
"hero": "a3f6f088-7b04-45e8-8d3b-d50c2d5b3a2d"
}, {
"courseName": "Sample course name 2",
"hero": "1b46227a-c496-43d2-be8e-1b0fa07cc94e"
}, {
"courseName": "Sample course name 3",
"hero": "c3bae6bf-2553-473a-9f30-f5c58c4fd608"
}];
我需要遍历所有课程,获取英雄uuid并对Heroes集合进行查询,然后在查询完成时将英雄信息添加到课程对象。
问题是所有查询都被快速触发,以至于MongoDB以任意顺序返回它们。它按顺序接收所有3个英雄uuids但有时会在第一个之前返回第三个,等等。有一种方法可以让一个查询完成然后再做另一个等等吗?
我现在正在做的是:
var newCourses = courses;
var counter = 0;
courses.forEach(function (course) {
var courseHeroUuid = course.hero;
// This function does the query by uuid and returns the doc
getHeroByUuid(courseHeroUuid, function (err, result) {
if (err) {
next(err);
}
// Replace the hero UUID with the hero document itself
newCourses[counter].hero = result[0];
if (++counter == courses.length) {
next(null, newCourses);
}
}
});
这是async.waterfall数组中的一个函数,这就是我跟踪计数器并调用next()继续运行的原因。我知道我可以使用async.each进行迭代,我试过它没有帮助。 这是我正在进行的查询。
function getHeroByUuid(heroUuid, callback) {
Hero.find({uuid: heroUuid}, function (err, result) {
if (err) {
callback(err);
}
callback(null, result);
})
}
发生这种情况: http://i.imgur.com/mEoQfgH.png
答案 0 :(得分:0)
很抱歉回答我自己的问题,但我发现了。我需要的就是我的鼻子。
我最终使用了async.whilst()
函数,文档是right here并完全按照我的需要执行 - 在返回前一个循环的结果后执行循环的下一次迭代。
我的代码现在看起来像这样:
var newCourses = courses;
var courseItemsLength = courses.length;
var counter = 0;
async.whilst(
function () {
return counter < courseItemsLength;
}, function (callback) {
var heroUuid = allCourses[counter].hero;
getHeroByUuid(heroUuid, function (err, result) {
if (err) {
next(err);
}
newCourses[counter].hero = result.name;
counter++;
if (err) {
callback(err);
}
callback();
});
}, function (err) {
if (err) {
next(err);
}
next(null, newCourses);
});