0

我正在使用 pdfkit 制作一个 pdf 文件,并将其作为附件发送到使用 nodemailer 的电子邮件,但它发送 0 字节 output.pdf。

我猜问题出在函数执行顺序上——它在创建 pdf 文件之前开始发送电子邮件。我只是不明白如何解决它...

app.post("/addressofpost", function(req, res){
  var abc = req.body.entpost;
  var subj = "pdf text"
"use strict"
const doc = new PDFDocument;
doc.pipe(fs.createWriteStream('output.pdf'));
doc.font('PalatinoBold.ttf')
   .fontSize(25)
   .text(subj, 100, 100);
doc.end();

async function main(){
  let account = await nodemailer.createTestAccount();
  let transporter = nodemailer.createTransport({
    host: "smtp settings",
    port: 465,
    secure: true,
    auth: {
      user: "mailuser",
      pass: "mailpass"
    }
  });
  let mailOptions = {
    from: '"Sender" <sender@gmail.com',
    to: '"Receiver" <receiver@gmail.com>',
    subject: "Subject",
    text: "email text",
    html: "HTML text"
  };
    let mailOptionsPrint = {
    attachments: [
        {  
              filename: 'output.pdf'
        }],
    from: '"Sergei Dudin" <dudinsergey@mail.ru>',
    to: '"Принтер" <info@moypohod.ru>',
    subject: "Subject",
    text: "email text",
    html: "HTML text"

  };
  let info = await transporter.sendMail(mailOptions)
  let infoPrint = await transporter.sendMail(mailOptionsPrint)
  console.log("Message sent: %s", info.messageId);
  console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
}
main().catch(console.error);
  console.log(abc);
  res.send('done');
 });

感谢您的任何帮助!

4

1 回答 1

0

你猜对了!

在我们解决问题之前,我建议您使app.post处理程序异步,这样您就不必在该处理程序中创建另一个异步函数。

app.post("/addressofpost", async (req, res) => {
  // ...
});

另外,我建议您尽可能不要混合使用回调和异步/等待。您可以为回调样式的异步函数创建包装函数,将它们转换为 Promise,然后await在您的 now-async post 处理程序中使用它们:

// I just extracted the pdf creation logic into a function
const createPdf = subj =>
  new Promise((resolve, reject) => {
    const doc = new PDFDocument();
    const writeStream = fs.createWriteStream("output.pdf");

    writeStream.on("finish", () => {
      resolve();
    });

    // TODO: handle errors and reject the promise accordingly

    doc.pipe(writeStream);
    doc
      .font("PalatinoBold.ttf")
      .fontSize(25)
      .text(subj, 100, 100);
    doc.end();
  });

有了这些你现在可以做的事情:

app.post("/addressofpost", async function(req, res) {
  const abc = req.body.entpost;
  const subj = "pdf text";

  await createPdf(subj);

  let account = await nodemailer.createTestAccount();
  let transporter = nodemailer.createTransport({
    host: "smtp settings",
    port: 465,
    secure: true,
    auth: {
      user: "mailuser",
      pass: "mailpass"
    }
  });
  let mailOptions = {
    from: '"Sender" <sender@gmail.com',
    to: '"Receiver" <receiver@gmail.com>',
    subject: "Subject",
    text: "email text",
    html: "HTML text"
  };
  let mailOptionsPrint = {
    attachments: [
      {
        filename: "output.pdf"
      }
    ],
    from: '"Sergei Dudin" <dudinsergey@mail.ru>',
    to: '"Принтер" <info@moypohod.ru>',
    subject: "Subject",
    text: "email text",
    html: "HTML text"
  };
  let info = await transporter.sendMail(mailOptions);
  let infoPrint = await transporter.sendMail(mailOptionsPrint);
  console.log("Message sent: %s", info.messageId);
  console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));

  console.log(abc);
  res.send("done");
});
于 2019-02-14T18:44:26.477 回答