Javascript 在nodejs中寻找循环和回调的正确模式(异步)

Javascript 在nodejs中寻找循环和回调的正确模式(异步),javascript,node.js,asynchronous,callback,mongoose,Javascript,Node.js,Asynchronous,Callback,Mongoose,我已经读了好几篇关于这个的帖子和文章,但我不太明白 在我的Mongoose模型中有一段代码,主要负责邀请人们参与项目。对于一些被邀请者,我会查看他们是否在数据库中,如果没有,我会继续创建他们并更新被邀请者列表中的id jslint抱怨循环,我正在努力处理回调(以及正确的整体模式,当您有一个循环,其中包含db SAVE和回调时)。显然,我希望循环完全完成,任何新用户都添加到db,ID在原始哈希(被邀请者)中更新,然后发生回调 ProjectSchema.methods.invite = funct

我已经读了好几篇关于这个的帖子和文章,但我不太明白

在我的Mongoose模型中有一段代码,主要负责邀请人们参与项目。对于一些被邀请者,我会查看他们是否在数据库中,如果没有,我会继续创建他们并更新被邀请者列表中的id

jslint抱怨循环,我正在努力处理回调(以及正确的整体模式,当您有一个循环,其中包含db SAVE和回调时)。显然,我希望循环完全完成,任何新用户都添加到db,ID在原始哈希(被邀请者)中更新,然后发生回调

ProjectSchema.methods.invite = function invite(invitees, callback) {
  var User = mongoose.model('User');
  var emails = _.pluck(invitees, 'email');
  // loop through invited hash to see if we already have those users in the db
  User.find({ 'email': { $in: emails}}, function (err, users) {
    for (var invited = 0; invited < invitees.length; invited++) {
      var found = false;
      // logic here to see if they are already users using the users param
      if (found) {
        // they are already in the db so do unrelated things.
      } else {
        // create new user
        var User = mongoose.model('User');
        var newUser = // set up new user here

        newUser.save(somecallback?);
        // update invitees list with id
      }
    }
    callback(err, invitees);
  });
};
ProjectSchema.methods.invite=函数invite(被邀请者,回调){
var User=mongoose.model('User');
var emails=uu.pull(被邀请者,'email');
//循环访问邀请的散列,查看数据库中是否已经有这些用户
查找({'email':{$in:emails}},函数(err,users){
for(var invested=0;invested
这里有几个问题:

  • 您正在for循环中声明局部变量。不建议这样做,因为JavaScript具有函数作用域,而不是块作用域(变量)

  • 您需要某种方法来同步您为保存到DB的每个用户所做的异步更改,即“等待”循环完成

  • 对于1,我建议您使用,即声明一个函数

    function processUser (invited) {
      // essentially the body of your for loop
    }
    
    然后调用
    invitees.map(processUser)

    2.问题更难:我建议您使用提供异步支持的库,例如

    为此,请让
    processUser
    函数返回一个Q承诺,该承诺在完成后得到解决,然后使用
    Q.all
    进行同步。例如:

    Q.all(invitees.map(processUser))
      .then(function (completions) {callback(null,invitees);},
            function (err) {callback(err,null);});
    
    总结:

    // import Q
    var Q = require('q');
    
    // ...
    
    ProjectSchema.methods.invite = function invite(invitees, callback) {
    
      var User = mongoose.model('User');
      var emails = _.pluck(invitees, 'email');
      // loop through invited hash to see if we already have those users in the db
    
      function processUser (invited) {
        var deferredCompletion = Q.defer();
    
        var found = false;
        // logic here to see if they are already users using the users param
        if (found) {
          // they are already in the db so do unrelated things.
          // ...
          deferredCompletion.resolve(true); // resolve with some dummy value
        } else {
          // create new user
          var newUser = // set up new user here
    
            newUser.save(function (err, user){
              if (err) {
                deferredCompletion.reject(err);
              } else {
                // update invitees list with id
                // ...
                deferredCompletion.resolve(true);
              }
            });
        }
        return deferredCompletion.promise;
      }
    
      Q.all(invitees.map(processUser))
        .then(function (completions) {
          callback(null,invitees);
        }, function (err) {
          callback(err,null);
        });
    };
    
    或者,您可以使用或。如果您需要处理大量用户,并且不希望数据库过载,则后者非常有用。