Node.js 尽管出现错误,async.series()仍继续执行下一个函数
我使用的是来自caolan异步模块的async.series()控制流。U NL就像doc解释的那样,它应该按顺序执行所有函数,一个接一个地执行,当一个函数调用回调时出错,它就会停止执行;如果其中一个函数出现错误,我的函数实际上会调用主回调函数,但很高兴继续按顺序执行其余函数Node.js 尽管出现错误,async.series()仍继续执行下一个函数,node.js,express,async.js,keystonejs,Node.js,Express,Async.js,Keystonejs,我使用的是来自caolan异步模块的async.series()控制流。U NL就像doc解释的那样,它应该按顺序执行所有函数,一个接一个地执行,当一个函数调用回调时出错,它就会停止执行;如果其中一个函数出现错误,我的函数实际上会调用主回调函数,但很高兴继续按顺序执行其余函数 async.series([ function (cb) { if (!req.body.join_firstname || !req.body.join_lastname || !req.bo
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('/');
});
例如,当我故意输入错误的密码确认值时,它抛出一个错误,执行回调并返回下一步()然后继续,甚至将用户保存在数据库中。显然,这不是预期的结果
有人知道我做错了什么吗?如果要停止当前函数的执行,调用回调是不够的。例如:
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
// ...
}
OP也可以使用
else
出于同样的目的Yes@soulcheck,我编辑了这篇文章以显示这一点作为示例。在我的示例中,将所有cb(true)和cb(null)更改为返回cb(…)会在抛出错误后停止执行其他函数。但是,在第二次调用此函数后,它仍然会在出现错误后停止进一步执行函数,但async现在会抛出以下错误:在我的示例中,将所有cb(true)和cb(null)更改为返回cb(…)会在抛出错误后停止进一步执行函数。但是,在第二次调用此函数后,它仍然会在出现错误后停止进一步执行这些函数,但async现在会抛出以下错误:错误:已调用回调。第二次如何调用它?Async.js是一个适当的系统,它阻止您创建一个多次执行的回调,请参见第19行