2014-03-25 40 views
0

我正在使用来自caolan异步模块的async.series()控制流。 U 不像文档的解释,它应该依次执行所有的函数,一个接一个地执行所有的函数,并且在一个错误的回调函数中停止;如果其中一个函数出现错误,我实际上会调用主回调函数,但随后会继续顺序执行其余函数。async.series()继续执行下一个函数,尽管有错误

async.series([ 

    function (cb) { 

     if (!req.body.join_firstname || !req.body.join_lastname || !req.body.join_email || !req.body.join_password) { 
      req.flash('error', 'Please enter a name, email and password.'); 
      cb(true); 
     } 

     if (req.body.join_password !== req.body.join_passwordConfirm) { 
      req.flash('error', 'Passwords must match.'); 
      cb(true); 
     } 

     if (req.body.join_email !== req.body.join_emailConfirm) { 
      req.flash('error', 'Emails must match.'); 
      cb(true); 
     } 

     cb(null); 

    }, 

    function (cb) { 

     keystone.list('User').model.findOne({ 
      email: req.body.join_email 
     }, function (err, user) { 

      if (err || user) { 
       req.flash('error', 'User already exists with that email address.'); 
       cb(true); 
      } 

      cb(null); 

     }); 

    }, 

    function (cb) { 

     var userData = { 
      name: { 
       first: req.body.join_firstname, 
       last: req.body.join_lastname 
      }, 
      email: req.body.join_email, 
      password: req.body.join_password 
     }; 

     var User = keystone.list('User').model, 
      newUser = new User(userData); 

     newUser.save(function (err) { 
      if (err) { 
       //if there's an error, don't send activation mail 
       cb(err); 
      } else { 
       newUser.activationEmail(function (err) { 
        if (err) { 
         //if we can't send activation email, 
         //delete user from db to prevent re-registration failing because of non-unique email 
         keystone.list('User').model.findOne({ 
          email: req.body.join_email 
         }).remove(function (err) { 
          req.flash('error', "Couldn't send an activation email. Contact support if this problem persists."); 
          cb(true); 
         }); 
        } else { 
         cb(err); 
        } 
       }); 
      } 
     }); 
    } 
], function (err) { 
    if (err) return next(); 
    req.flash('success', "Hi, " + req.body.join_firstname + "! We've sent you an activation email. Please check your inbox and spam folder."); 
    return res.redirect('/'); 
}); 

例如,当我故意输入错误密码确认值,它抛出一个错误,执行回调return next();,然后就继续,甚至保存在数据库中的用户。显然这不是预期的结果。

任何人都知道我在做什么错在这里?

回答

2

如果要执行当前函数来停止,调用回调是不够的。例如:

function(cb) { 

    if (!req.body.join_firstname || !req.body.join_lastname || !req.body.join_email || !req.body.join_password) { 
     req.flash('error', 'Please enter a name, email and password.'); 
     cb(true); // will add this callback to the stack 
    } 
    // continuing here 
    // ... 
} 

要么改变你的if-then-结构:

function(cb) { 

    if (!req.body.join_firstname || !req.body.join_lastname || !req.body.join_email || !req.body.join_password) { 
     req.flash('error', 'Please enter a name, email and password.'); 
     cb(true); // will add this callback to the stack 
    } else if (req.body.join_password !== req.body.join_passwordConfirm) { 
     //... 
    } 
    // no more code here 
} 

或退货:

function(cb) { 

    if (!req.body.join_firstname || !req.body.join_lastname || !req.body.join_email || !req.body.join_password) { 
     req.flash('error', 'Please enter a name, email and password.'); 
     return cb(true); // will add this callback to the stack and return 
    } 
    // will only be executed if the if is false 
    // ... 
} 
+0

OP也可以使用'else'为了同样的目的 – soulcheck

+0

是@soulcheck ,我编辑了这篇文章以表明这也是一个例子。 – Sonata

+0

在我的示例中,更改所有cb(true)和cb(null)以返回cb(...)会在抛出错误后停止执行其他函数。但是,在第二次调用此函数后,它仍会在发生错误后停止进一步执行函数,但异步现在会抛出以下错误: – Ventis

相关问题