Async/await 函数在创建写入流后不等待
Async/await function not awaiting after creating write stream
我有一个节点应用程序,它使用 express 进行路由,使用 pdfmake npm 生成 pdf 文档。单击一个按钮,我发出一个 http 请求,从数据库中检索数据,生成一个 pdf 文档,然后保存到磁盘。但是,我的 async/await 函数似乎只在我使用 fs.createWriteStream(path)
创建写入流之前起作用。之后的所有 async/await 似乎都被忽略了。此外,这只发生在生产服务器上。在本地调试我的应用程序时,ALL async/await 函数似乎有效。关于为什么会发生这种情况有什么想法吗?
快递路线:
router.patch('/:id(\d+)/approve', async function (req, res) {
try {
let id = req.params.id
const invoice = await db.fetchInvoiceById(id)
const harvestInvoice = await harvest.getInvoiceById(invoice.harvest_id)
// generate invoice pdf
await pdf.generateInvoice(invoice, harvestInvoice)
res.status(200).json({ id: id })
} catch (error) {
res.status(400).json({ error: 'something went wrong' })
}
})
函数:
async function SLEEP5() {
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('DONE');
}, 5000);
});
}
function test(doc, invoicePath) {
return new Promise((resolve, reject) => {
const writeStream = fs.createWriteStream(invoicePath)
writeStream.on("finish", () => { resolve(true) })
writeStream.on("error", () => { reject(false) })
doc.pipe(writeStream)
doc.end()
})
}
exports.generateInvoice = async function generateInvoice(invoice, harvestInvoice) {
const invoicePath = `${__dirname}\invoice_${invoice.number}.pdf`
let printer = new PdfPrinter(fonts)
let def = { // pdf defined here }
// generate invoice PDF
let doc = printer.createPdfKitDocument(def, {})
await SLEEP5() // THIS IS AWAITED
await test(doc, invoicePath)
await SLEEP5() // THIS IS NOT AWAITED FOR SOME REASON
}
我在 aws ec2 服务器上使用 PM2 运行 这个节点应用程序,我使用 pdfmake
版本 0.2.4
我不知道 printer.createPdfKitDocument(def, {})
到底做了什么,但是
let doc = printer.createPdfKitDocument(def, {})
await sleep(5)
await writeStreamToFile(doc, invoicePath)
确实看起来有问题。如果 doc
在创建时没有暂停,它可能会 运行 并在您还在睡觉时完成 ,然后将任何内容通过管道传输到您的写入流中,这将永远不会发出finish
或 error
事件。所以删除 await sleep(5)
,然后 立即 执行 doc.pipe(writeStream)
并且 立即 开始监听事件。
如果你坚持要等,要么
let doc = printer.createPdfKitDocument(def, {})
await Promise.all([
sleep(5),
writeStreamToFile(doc, invoicePath),
])
或尝试
const doc = printer.createPdfKitDocument(def, {})
doc.pause()
await sleep(5)
await writeStreamToFile(doc, invoicePath)
(另一种解释当然是 createPdfKitDocument
创建了一个 never-ending 流,或者在没有发出 error
事件的情况下发生错误,等等,这将导致 promise 不被执行已解决)。
我明白我的问题是什么了。事实证明,我正在使用 pm2 start appName --watch to 运行 我的应用程序。我正在将 pdf 写入应用程序中的目录。 PM2 在写入 pdf 时检测到变化并会重新启动应用程序(因为 --watch 标志),导致我看到的所有问题。
我有一个节点应用程序,它使用 express 进行路由,使用 pdfmake npm 生成 pdf 文档。单击一个按钮,我发出一个 http 请求,从数据库中检索数据,生成一个 pdf 文档,然后保存到磁盘。但是,我的 async/await 函数似乎只在我使用 fs.createWriteStream(path)
创建写入流之前起作用。之后的所有 async/await 似乎都被忽略了。此外,这只发生在生产服务器上。在本地调试我的应用程序时,ALL async/await 函数似乎有效。关于为什么会发生这种情况有什么想法吗?
快递路线:
router.patch('/:id(\d+)/approve', async function (req, res) {
try {
let id = req.params.id
const invoice = await db.fetchInvoiceById(id)
const harvestInvoice = await harvest.getInvoiceById(invoice.harvest_id)
// generate invoice pdf
await pdf.generateInvoice(invoice, harvestInvoice)
res.status(200).json({ id: id })
} catch (error) {
res.status(400).json({ error: 'something went wrong' })
}
})
函数:
async function SLEEP5() {
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('DONE');
}, 5000);
});
}
function test(doc, invoicePath) {
return new Promise((resolve, reject) => {
const writeStream = fs.createWriteStream(invoicePath)
writeStream.on("finish", () => { resolve(true) })
writeStream.on("error", () => { reject(false) })
doc.pipe(writeStream)
doc.end()
})
}
exports.generateInvoice = async function generateInvoice(invoice, harvestInvoice) {
const invoicePath = `${__dirname}\invoice_${invoice.number}.pdf`
let printer = new PdfPrinter(fonts)
let def = { // pdf defined here }
// generate invoice PDF
let doc = printer.createPdfKitDocument(def, {})
await SLEEP5() // THIS IS AWAITED
await test(doc, invoicePath)
await SLEEP5() // THIS IS NOT AWAITED FOR SOME REASON
}
我在 aws ec2 服务器上使用 PM2 运行 这个节点应用程序,我使用 pdfmake
版本 0.2.4我不知道 printer.createPdfKitDocument(def, {})
到底做了什么,但是
let doc = printer.createPdfKitDocument(def, {})
await sleep(5)
await writeStreamToFile(doc, invoicePath)
确实看起来有问题。如果 doc
在创建时没有暂停,它可能会 运行 并在您还在睡觉时完成 ,然后将任何内容通过管道传输到您的写入流中,这将永远不会发出finish
或 error
事件。所以删除 await sleep(5)
,然后 立即 执行 doc.pipe(writeStream)
并且 立即 开始监听事件。
如果你坚持要等,要么
let doc = printer.createPdfKitDocument(def, {})
await Promise.all([
sleep(5),
writeStreamToFile(doc, invoicePath),
])
或尝试
const doc = printer.createPdfKitDocument(def, {})
doc.pause()
await sleep(5)
await writeStreamToFile(doc, invoicePath)
(另一种解释当然是 createPdfKitDocument
创建了一个 never-ending 流,或者在没有发出 error
事件的情况下发生错误,等等,这将导致 promise 不被执行已解决)。
我明白我的问题是什么了。事实证明,我正在使用 pm2 start appName --watch to 运行 我的应用程序。我正在将 pdf 写入应用程序中的目录。 PM2 在写入 pdf 时检测到变化并会重新启动应用程序(因为 --watch 标志),导致我看到的所有问题。