Node.js 尽管出现错误,async.series()仍继续执行下一个函数

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

我使用的是来自caolan异步模块的async.series()控制流。U NL就像doc解释的那样,它应该按顺序执行所有函数,一个接一个地执行,当一个函数调用回调时出错,它就会停止执行;如果其中一个函数出现错误,我的函数实际上会调用主回调函数,但很高兴继续按顺序执行其余函数

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行