我使用的是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()查找属于此用户的所有组织并更新此用户的组织数组属性
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'); }); }); }); }
问题:
- Process.exit(0)在saddOrgsToOneUser()的查询/更新完成之前被调用。例如,如果saddOrgsToOneUser()只包含一个console.log,那么它的行为就像预期的那样,但是查询当然是异步触发的。
- 如果我注释掉Process.exit(0),脚本永远不会停止,但是查询会按预期执行。
- 由于脚本将有进一步嵌套查询,我需要一个更好的方法来手动杀死这个脚本…
- 如何嵌套查询和迭代他们的结果正确完成?
非常感谢,Manuel
addOrgsToOneUser是异步的。next()需要在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
});
});
});
}