我正在使用waterline + sails作为一个api,我有以下函数嵌套exec()
调用。
AcademyService.getAll().exec(function (error, data) {
if (error) {
return res.json({result: false, message: error});
}
var academies = data;
for (var i = 0; i < Object.keys(academies).length; i++) {
var user_id;
user_id = academies[i].academy_user_id;
(function (index) {
UserService.getOneById(user_id).exec(function (error, data) {
if (error) {
academies[index].academy_user_id = null;
}
academies[index].academy_user_id = data.user_fname+" "+data.user_lname;
});
})(i);
}
return res.json({result: true, academies: academies});
});
上面代码的问题在于,最后一个return语句没有更新的academies
对象。即它没有academy_user_id
的更新值。我将此归因于调用的异步行为,我认为当我们到达最后一个返回时,UserService
的异步调用仍在循环中运行,并且未传递更新的academies
对象。< / p>
现在,一个仓促的解决方案是使用循环结束检查从academies
回调中返回UserService.getOneById
对象,但这似乎不是正确的方法。那么,我们能以某种方式同步地进行内部exec()
吗?
答案 0 :(得分:1)
Sails捆绑了async
库,非常适合这种情况。 Async在sails中全局可用,因此您不需要它,甚至可以将其添加到依赖项中。
使用async.each
代替你的for循环。
这样的事情应该有效
AcademyService.getAll().exec(function(error, academies) {
if (error) {
return res.json({
result: false,
message: error
});
}
async.each(
academies,
function (academy, cb) {
var user_id = academy.user_id;
UserService.getOneById(user_id).exec(function (err, user) {
if (err) {
academy.academy_user_id = null;
}
else {
academy.academy_user_id = user.user_fname + ' ' + user.user_lname;
}
return cb();
});
},
function (err) {
if (err) {
return res.json({
result: false,
message: err
});
}
return res.json({
result: true,
academies: academies
});
}
);
});