Passport.js -- 如何使用异步呈现电子邮件

Passport.js -- how to use render email asynchronously

我是 运行 Express 用 Sequelize/MariaDB 和 Passport.js 进行用户身份验证。

我在注册部分(有效),但我似乎无法呈现 return 一封激活电子邮件,要求他们确认他们的电子邮件。

passport.js(含认证策略)

passport.use('user-signup-email', new LocalStrategy({
    //Process/validate input, check database for existing emails, create user, add to database...

    ...
    if (newUser) {
        var token = jwt.sign( { data: newUser.id }, newUser.login_pass + "-" + newUser.account_created);
        var URLdata = { 
            id:                newUser.id,
            expiration_time:   Date.now() + 86400000,   //24 hours
            url:               token,
            email_info:        mail.createActivationEmail(req.app, newUser.login_key, newUser.user_alias, token)                        
        };

        console.log("info: " + URLdata.email_info);

        ... 
            //Store dynamic URL and email contents (in case of resending) in database with expiration time
            //And then send the email that was just rendered
    }

mail.js

exports.createActivationEmail = (app, recipientAddress, userName, url) => {
    app.render('emails/activation_email', {    
        layout: false,
        page_title: 'Please confirm your account!',
        dynamic_url: url
    }, function(err, rendered) {
        if (err) {
            console.log("Q [" + err + "]");
        }

        console.log("R " + rendered.toString());
        return {  
            from:       adminEmailAddress,
            to:         recipientAddress,
            cc:         false,
            bcc:        false,
            subject:    'Welcome to example.com ' + userName + '!',
            html:       rendered.toString(),
            text:       "TO DO" 
        };
    });
};

passport.js 中的最后一个 console.log 显示 "info: undefined." 但是,如果我在 return 之前在 mail.js 模块中打印输出,那很好。

我猜这是一个异步问题?我该如何解决?
在这种情况下,我对 promises 和 async-await 块还有点不清楚。

在此先感谢您提供的任何帮助!

你误解了回调函数。 回调是(应该,当你写它们时)异步的: https://nemethgergely.com/async-function-best-practices/ How to write asynchronous functions for Node.js

我更改了您的 createActivationEmail 功能。 最后一个参数现在是一个回调,它会在您的代码 app.redner 完成时被调用。

passport.use('user-signup-email', new LocalStrategy({
    //Process/validate input, check database for existing emails, create user, add to database...

    // ...
    if(newUser) {

        var token = jwt.sign({ data: newUser.id }, newUser.login_pass + "-" + newUser.account_created);
        mail.createActivationEmail(req.app, newUser.login_key, newUser.user_alias, token, (err, email_info) => {



            var URLdata = {
                id: newUser.id,
                expiration_time: Date.now() + 86400000,   //24 hours
                url: token,
                email_info
            };


            console.log("info: " + URLdata.email_info);

            //... 
            //Store dynamic URL and email contents (in case of resending) in database with expiration time
            //And then send the email that was just rendered


        });

    }

}));

exports.createActivationEmail = (app, recipientAddress, userName, url, done) => {
    app.render('emails/activation_email', {    
        layout: false,
        page_title: 'Please confirm your account!',
        dynamic_url: url
    }, function(err, rendered) {

        if (err) {
            console.log("Q [" + err + "]");
            cb(err);
            return;
        }

        console.log("R " + rendered.toString());
        
        done(null, {  
            from:       adminEmailAddress,
            to:         recipientAddress,
            cc:         false,
            bcc:        false,
            subject:    'Welcome to example.com ' + userName + '!',
            html:       rendered.toString(),
            text:       "TO DO" 
        });

    });
};