javascript - 如何修复函数执行顺序
问题描述
我正在使用 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');
});
感谢您的任何帮助!
解决方案
你猜对了!
在我们解决问题之前,我建议您使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");
});
推荐阅读
- c - 通过 argv 操作进程名称和参数
- serialization - 序列化数据库中的数据
- django - Django注释:最大异物的总和
- cypress - 访问“it”“测试用例”中的夹具数据
- javascript - CSS 格式不适用于 window.print()
- javascript - Core 2.2:在父网站窗口内打开子网站并处理来自子网站的事件
- node.js - 使用 npm 安装 expo-cli 时遇到问题
- python - 如何解码这种整数格式?
- visual-studio - Visual Studio 2019 Azure 调试 - 远程调试
- spring - 如何将 /*+Parallel*/ 添加到休眠名称查询