背景:我一直在使用Lambda函数通过Mailgun服务发送事务性电子邮件。我之所以选择使用node.js来实现服务器,是因为我以前曾经使用过这种语言,但是我在服务器端工作的经验并不多,因此我一直在努力地了解正在发生的事情。
任务:想法是向注册了此特定消息的多个收件人发送个性化电子邮件,这些收件人仅对Lambda函数执行一个请求。
问题:为了执行上述任务,我根据Mailgun文档和API参考提出了这个基本实现。我使用了forEach
,因此可以向每位收件人发送自定义电子邮件,这正是我期望达到的目标。
在本地测试时,一切正常。执行请求,并按预期发送电子邮件。
但是,在将代码部署到AWS之后,奇怪的行为开始发生。当执行请求时,似乎代码的执行在完成之前停止了,这导致仅发送了几封电子邮件。总是发生的另一件事是,lambda函数的第一次调用不是触发sendBulkTemplatedEmail
,而是在第一次尝试之后开始进行。
这就是CloudWatch上的日志的样子:
每条蓝线是我使用邮递员执行的请求。为了进行测试,我总是使用3个收件人作为电子邮件。红线表示我已添加到代码中的console.log(body)
。当日志中出现诸如{id:'<201910100230 ..之类的消息时,表示电子邮件已成功发送。
第一个请求:未发送电子邮件。
第二个请求:已发送两封电子邮件。
第三个请求:已发送三封电子邮件,第二个请求中应发送的电子邮件。
第四个请求:已发送三封电子邮件(预期行为)
第五个请求:已发送三封电子邮件(预期行为)
第六个请求:已发送三封电子邮件(预期行为)
我不明白为什么在远程运行我的代码时会发生这种情况,而在本地运行时却不会发生这种情况。我的猜测是这些问题在某种程度上与lambda函数的超时有关,但我无法解决它。
对此有何想法?
[没有查看您的处理程序代码,我怀疑两种可能的情况:
context.callbackWaitsForEmptyEventLoop = false
,这会导致在调用callback
函数时lambda结束。查看代码段,您也没有正确返回处理程序可以等待的一系列发送电子邮件保证。为此,请将sendBulkTemplateEmail
函数更改为:
const sendBulkTemplateEmail = (config) => (group) => {
return group.participants.map((participant) => {
//processing code that you have been doing;
return mailgun.messages().send(data)})
}
}
这样,它返回一个可以在处理程序中等待的promise数组:
const handler = async (event) => {
// event processing
await Promise.all(sendBulkTemplateEmail(config)(group))
}
在较新版本的lambda处理程序中,您不再需要调用callback
来解决异步lambda。
有关lambda处理程序的参考,您可以参考此文档AWS Lambda Function Handler in Node.js:
第三个参数,回调,是一个可以在非异步处理程序中调用以发送响应的函数。回调函数带有两个参数:错误和响应。当您调用它时,Lambda等待事件循环为空,然后将响应或错误返回给调用者。响应对象必须与JSON.stringify兼容。
对于异步处理程序,您将响应,错误或承诺返回给运行时,而不使用回调。
希望此帮助解决您的奥秘! (这肯定对我有用,因为我花了数小时的尝试和错误,最后在我的承诺中增加了一个等待,终于使它正常工作。)