Javascript 不返回承诺时的nodemailer延迟

Javascript 不返回承诺时的nodemailer延迟,javascript,firebase,promise,google-cloud-functions,nodemailer,Javascript,Firebase,Promise,Google Cloud Functions,Nodemailer,我在Firebase中有一个云函数,在一系列承诺调用中,该函数以调用此函数结束: function sendEmail() { return new Promise((accept) => { const Email = require('email-templates'); const email = new Email({...}); email.send({...}).then(() => { console.log('Email sen

我在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。

我认为这里有两个方面是混合的

问题的一个方面涉及云功能上下文中的承诺。在调用
res.send()
之前,需要解析云函数中的承诺,因为在调用之后,函数将立即关闭,并且无法保证未解析的承诺将在函数实例终止之前完成,请参见此。您最好不要调用
res.send()
,而是返回Firebase中所示的承诺结果,这里的关键是确保承诺得到正确解析,例如使用类似
return myPromise()的习惯用法。然后(console.log)将强制承诺解决方案

另外,正如Bergi在评论中指出的,第一个代码片段使用了带有承诺的反模式,第二个代码片段更加简洁和清晰。如果您在UI中遇到延迟,那么执行可能会冻结,等待函数响应,您可能会考虑这是否可以在您的特定用例中避免。


综上所述,您最近提出的创建一个单独的功能来处理电子邮件发送过程的想法也可能会缩短响应时间,甚至从分离关注点的角度来看更有意义。要走这条路,我建议从主功能发送一条PubSub消息,以便第二条发送电子邮件。此外,该函数还允许配置可能有用的选项,以确保邮件在出现最终错误的情况下发送。上述链接的问题中也建议采用这种方法。

是的,避免使用。如果你愿意,你的功能根本不应该返回一个承诺。“电子邮件再过15分钟就不会发送了。”-这对我来说真的没有意义。我怀疑这是由这个code.Bergi中的更改引起的,因此我的问题是,当我返回email.send()时,电子邮件会在10秒后发送,一切正常。当我使用Promise构造函数反模式时,结果是一封长时间不发送的电子邮件。。。我没有撒谎,我发誓!;)我注意到这是一个类似的问题:请编辑该问题,以显示显示问题的完整最小函数。您永远不应该忽略云函数中的承诺,我们需要了解您是如何在上下文中使用此函数的。