Как исправить порядок выполнения функции - PullRequest
0 голосов
/ 14 февраля 2019

Я делаю PDF-файл с помощью pdfkit и отправляю его в виде вложения в электронное письмо с помощью nodemailer, но он отправляет 0-байтовый выходной файл .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');
 });

Спасибо за любую помощь!

1 Ответ

0 голосов
/ 14 февраля 2019

Вы правильно догадались!

Прежде чем мы приступим к решению проблемы, я рекомендую вам сделать обработчик app.post асинхронным, чтобы вам не нужно было создавать другую асинхронную функцию в этом обработчике.

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

Кроме того, я рекомендую вам не смешивать обратные вызовы и async / await, когда это возможно.Вы можете создавать функции-оболочки для асинхронных функций в стиле обратного вызова, преобразовывать их в обещания, а затем await для тех, которые находятся в вашем теперь-асинхронном обработчике сообщений:

// 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");
});
...