我正在使用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
        });


    });
  });
}

10-05 22:37