我正在使用Sails v0.11,并正在开发一个独立的导入器脚本,以便将数据导入到mongoDB,并且-现在是不起作用的部分-构建模型之间的关联。
在此过程中,我在模型中引入了临时帮助器属性,以查找关联的记录,并用真实的MongoDB _ids替换它们。
该脚本启动Sails,以便能够使用其功能(吃水线等):
var app = Sails();
app.load({
hooks: { grunt: false },
log: { level: 'warn' }
}, function sailsReady(err){
processUsers()查找所有用户及其_id,并对其进行迭代以调用第二个函数addOrgsToOneUser()
var processUsers = function() {
// Iterate through all users in order to retrieve their _ids and
app.models['user'].native(function(err, collection) {
collection.find({}, projectionOrgInUser).toArray(function (err, users) {
Async.eachSeries(users, function (user, next){
// prepare userInOrgs
whereUserInOrg = { orgId: { $in: userInOrgs } };
//This is invoking
addOrgsToOneUser(user, whereUserInOrg);
next();
}, function afterwards (err) {
if (err) {
console.error('Import failed, error details:\n',err);
return process.exit(1);
}
console.log("done");
return process.exit(0); // This returns too early, not executing the addOrgsToOneUser
});
});
});
};
addOrgsToOneUser()查找属于此用户的所有组织,然后更新此用户的orgs数组属性
var addOrgsToOneUser = function(user, whereUserInOrg) {
var projectionUserInOrg = "...";
// Find all orgs that this user is associated to and store it in inOrgs
app.models['org'].native(function(err, collection) {
collection.find(whereUserInOrg, projectionUserInOrg).toArray(function (err, orgs) {
// prepare inOrgs which is needed for updating
//update user to have an updated orgs array based on inOrgs.
app.models['user'].update({'id' : user._id.toString()}, {'orgs': inOrgs}).exec(function afterwards(err, updated){
console.log('Updated user ' + user._id.toString() + ' to be in their orgs');
});
});
});
}
问题:
在saddOrgsToOneUser()的查询/更新完成之前,将调用Process.exit(0)。例如,如果saddOrgsToOneUser()仅包含console.log,则它的行为符合预期,但是查询当然是异步触发的。
万一我注释掉Process.exit(0),脚本将永远不会停止,但是查询将按预期执行。
由于脚本将具有更多的嵌套查询,因此我需要一种更好的方法来手动杀死此脚本...
嵌套查询和对其结果进行迭代如何正确完成?
非常感谢你,
曼努埃尔
最佳答案
addOrgsToOneUser是异步的。在addOrgsToOneUser内部完成所有操作后,需要调用next()。我要做的方法是传入一个回调(下一个),并在一切完成后调用它。所以电话是
addOrgsToOneUser(user, whereUserInOrg, next);
并且addOrgsToOneUser将有一个额外的参数:
var addOrgsToOneUser = function(user, whereUserInOrg, callback) {
var projectionUserInOrg = "...";
// Find all orgs that this user is associated to and store it in inOrgs
app.models['org'].native(function(err, collection) {
collection.find(whereUserInOrg, projectionUserInOrg).toArray(function (err, orgs) {
// prepare inOrgs which is needed for updating
//update user to have an updated orgs array based on inOrgs.
app.models['user'].update({'id' : user._id.toString()}, {'orgs': inOrgs}).exec(function afterwards(err, updated){
console.log('Updated user ' + user._id.toString() + ' to be in their orgs');
callback(); // your original next() is called here
});
});
});
}