AWS - Lambda 函数不等待等待

use*_*od2 6 javascript async-await aws-lambda

我正在使用 AWSs API Gateway 以及用于 API 的 Lambda 函数。

在我的 Lambda 函数中,我有以下(简化的)代码,但是我发现它await sendEmail没有得到尊重,而是不断返回undefined

exports.handler = async (event) => {
    let resultOfE = await sendEmail("old@old.com", "new@new.com")
    console.log(resultOfE)
}

async function sendEmail(oldEmail, newEmail) {
    var nodemailer = require('nodemailer');

    var transporter = nodemailer.createTransport({
        service: 'gmail',
        auth: {
            user: 'xxx',
            pass: 'xxx'
        }
    });

    transporter.sendMail(mailOptions, function (error, info) {
        if (error) {
            console.log(error);
            return false
        } else {
            console.log('Email sent: ' + info.response);
            return true
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*a X 5

因为你await sendMail,这需要sendMail返回一个Promise- 你的代码使用回调来处理异步,所以

  • async sendMail没有做任何事情(除了化妆sendMail回报承诺立即做出决议undefined
  • 您需要更改 sendMail 以返回一个 Promise(它不需要,async因为它不需要await

下面的代码应该这样做 -

var nodemailer = require('nodemailer'); // don't put require inside a function!!

exports.handler = async (event) => {
    const resultOfE = await sendEmail("old@old.com", "new@new.com")
    console.log(resultOfE)
}

//doesn't need async, since there will be no await
function sendEmail(oldEmail, newEmail) {
    return new Promise((resolve, reject) => { // note, reject is redundant since "error" is indicated by a false result, but included for completeness
        const transporter = nodemailer.createTransport({
            service: 'gmail',
            auth: {
                user: 'xxx',
                pass: 'xxx'
            }
        });
        transporter.sendMail(mailOptions, (error, info) => {
            if (error) {
                console.log(error);
                resolve(false);
            } else {
                console.log('Email sent: ' + info.response);
                resolve(true);
            }
        });
        // without the debugging console.logs, the above can be just
        // transporter.sendMail(mailOptions, error => resolve(!error));
    });
}
Run Code Online (Sandbox Code Playgroud)

根据@ThalesMinussi 的评论,transporter.sendMail如果您不提供回调函数,则返回一个 Promise,因此您可以编写:(sendEmail 现在是异步的)

async function sendEmail(oldEmail, newEmail) {
    const transporter = nodemailer.createTransport({
        service: 'gmail',
        auth: {
            user: 'xxx',
            pass: 'xxx'
        }
    });
    try {
        const info = await transporter.sendMail(mailOptions);
        console.log('Email sent: ' + info.response);
        return true;
        }
    } catch (error) {
        console.log(error);
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)