我在Firebase中有一个云函数,在一系列的承诺调用中,以调用这个函数结束:
function sendEmail() {
return new Promise((accept) => {
const Email = require('email-templates');
const email = new Email({...});
email.send({...}).then(() => {
console.log('Email sent');
}).catch((e) => {
console.error(e);
});
accept();
});
}我很清楚,email.send()返回了一个承诺。
function sendEmail() {
const Email = require('email-templates');
const email = new Email({...});
return email.send({...});
}这通常会导致UI挂起相当长的时间(10+秒),因为解决问题的承诺所需的时间等于发送电子邮件所需的时间。
所以我觉得第一种方法会更好。只需异步调用email.send(),它最终将发送电子邮件,并向客户端返回一个响应,无论该邮件是否已完成往返行程。
第一种方法是给我一些问题。云功能必须更快地完成执行,从而为用户提供更好的体验,然而,电子邮件不会发送另一个15+分钟。
我正在考虑另一种方法,即我们有一个单独的云函数钩子来处理电子邮件发送,但我想先问StackOverflow。
发布于 2020-10-19 09:19:47
我认为这里有两个方面的问题。
问题的一个方面涉及云功能上下文中的承诺。在调用res.send()之前,需要解析云函数中的承诺,因为在此调用之后,函数将被关闭,无法保证未解决的承诺将在函数实例终止之前完成,请参阅此问题。您最好不要调用res.send(),而是返回诺言的结果,如Firebase 文档中所示,这里的关键是确保承诺得到正确的解决--例如,使用像return myPromise().then(console.log);这样的成语来强制承诺解析。
另外,正如Bergi在评论中指出的那样,第一个片段使用了带有承诺的反模式,而第二个则更加简洁和清晰。如果您在UI中遇到延迟,很可能在等待函数响应时执行会被冻结,并且您可能会考虑是否可以在特定的用例中避免这种情况。
尽管如此,创建一个单独的功能来处理电子邮件发送过程的最后一个想法也可能会减少响应时间,甚至从不同的角度来看可能更有意义。要走这条路,我建议从主函数发送一条PubSub消息,以便第二条发送电子邮件。此外,PubSub触发函数允许配置重试政策,这可能有助于确保在最终错误的上下文中发送邮件。上述问题中也提出了这一办法。
https://stackoverflow.com/questions/64299062
复制相似问题