Javascript - 部分应用程序参数之间的依赖关系

Javascript - Dependency between arguments of partial applications

简介

我已经在我的模块中创建了给定的部分应用程序:

// GENERIC
const sendEmail = (subject, template) =>
  async (to, ...props) => {
    const mailsRef = firestore.collection("mails");
    const html = template(...props);
    const mail = {
      to,
      message: {
        subject,
        html,
      },
    };

    await mailsRef.add(mail);

    functions.logger.log("Email queued for delivery!");
  };

// SPECIFIC
const sendUpdatePasswordEmail = sendEmail(
  "Your password has been updated.",
  updatePasswordHTMLTemplate
);

const sendSignUpWelcomeEmail = sendEmail(
  "Welcome to Binance!",
  signUpWelcomeHTMLTemplate
);

const sendBitcoinAddressUpdatedEmail = sendEmail(
  "Your bitcoin address has been updated.",
  bitcoinWalletAddressHTMLTemplate
);

如您所见,我的 sendUpdatePasswordEmail 将主题和 HTML 模板生成器传递给 sendEmail 函数。

这是我的 updatePasswordHTMLTemplate 的样子:

const updatePasswordHTMLTemplate = (language) => `
  <!DOCTYPE html>
  <html lang="${language}">
  ...
  <body>
    <h1>${t("auth.password.update.title", language)}</h1>
  </body>
  </html>
`;

如您所见,我正在将发送给最终用户的电子邮件国际化,使用某种 i18n

问题

我遇到的问题是我需要一种方法将用户的语言作为参数传递给我的 sendUpdatePasswordEmail 函数。而且,我还需要翻译邮件的主题:

const sendUpdatePasswordEmail = sendEmail(
  "Your password has been updated.", <--- t("auth.password.update.subject", language)
  updatePasswordHTMLTemplate
);

我应该在这里使用什么设计模式吗?我的意思是,如您所见,我使用部分应用程序是为了“概括”我的代码,使其更具可读性,但大问题来自主题翻译...

这是我使用我描述的方法的方式:

const { email, language } = context.auth.token;

await sendUpdatePasswordEmail(email); // I need to pass the language!

有什么想法吗?谢谢。


我想过做这样的事情:

const sendUpdatePasswordEmail = (language) => sendEmail(
  t("subject.scope", language), 
  updatePasswordTemplate,
  language
);

但是,我将不得不使用如下方法:

sendUpdatePasswordEmail(language)(emailAddress);

而且我不喜欢它(不是一种干净的方式)。

我建议简单地使 subject 参数也成为接受语言的函数,就像您的 template 参数已经是:

const makeSendEmail = (subjectTemplate, bodyTemplate) => async (to, ...props) => {
    const mailsRef = firestore.collection("mails");
    const subject = subjectTemplate(...props);
    const html = bodyTemplate(...props);
    const mail = {…};
    …
};

然后使用

const sendUpdatePasswordEmail = makeSendEmail(
  (language) => t("subject.scope", language), 
  updatePasswordTemplate
);

并致电

sendUpdatePasswordEmail(emailAddress, language);

和以前一样