[英]Async/await function not awaiting after creating write stream
我有一个节点应用程序,它使用 express 进行路由,使用 pdfmake npm 生成 pdf 文档。 单击一个按钮,我发出一个 http 请求,从数据库中检索数据,生成一个 pdf 文档,并保存到磁盘。 但是,我的 async/await 函数似乎只在我使用fs.createWriteStream(path)
创建写入 stream 之前起作用。 之后的所有异步/等待似乎都被忽略了。 此外,这只发生在生产服务器上。 在本地调试我的应用程序时,所有异步/等待功能似乎都有效。 关于为什么会发生这种情况的任何想法?
快递路线:
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
}
我正在使用 PM2 在 aws ec2 服务器上运行此节点应用程序,我使用的是0.2.4版的 pdfmake
我弄清楚我的问题是什么。 事实证明,我正在使用pm2 start appName --watch来运行我的应用程序。 我正在将 pdf 写入应用程序中的目录。 PM2 在写入 pdf 时检测到变化,并会重新启动应用程序(因为--watch标志),导致我看到的所有问题。
我不知道printer.createPdfKitDocument(def, {})
到底做了什么,但是
let doc = printer.createPdfKitDocument(def, {})
await sleep(5)
await writeStreamToFile(doc, invoicePath)
当然看起来有问题。 如果doc
在创建时没有暂停,它可能会在您还在睡觉时运行并完成,然后 pipe 没有任何内容写入您的 write stream ,它永远不会发出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
创建了一个永无止境的 stream,或者没有发出error
事件的错误,等等,这将导致 promise 无法解决)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.