同步函数表现为异步如何await?html-pdf执行顺序异常求解
问题原因
你遇到的执行顺序错乱是典型的回调式异步代码执行时序问题,和TypeScript类型提示没有关系:
html-pdf是比较老的Node包,它的toBuffer方法是标准的错误优先回调风格异步API,不会阻塞后续同步代码执行- 你调用
toBuffer传入回调函数后,JS会把这个回调暂存到异步任务队列,立刻往下执行外层的日志打印、uploadFile调用,等所有同步代码跑完,才会回头执行回调里的blob、pdfSize赋值逻辑,这就是为什么你在外层拿到的永远是undefined - 直接
await pdf.create()不生效是因为pdf.create()返回的是支持链式调用的实例对象,不是Promise,await非Promise值不会产生任何等待效果。
修复方案
把回调风格的toBuffer包装成Promise,配合async/await实现按预期顺序执行,修改后的代码如下:
resolve: async (parent, args, { req }) => { try { // ...其余原有前置逻辑 const pdfId = uuidv4(); // 包装回调为Promise,等待PDF生成完成再往下走 const { blob, pdfSize } = await new Promise<{ blob: Blob; pdfSize: number; }>((resolve, reject) => { pdf.create(args.data.htmlTemplate, { // ...原有PDF配置项 }).toBuffer((err, buffer) => { if (err) { return reject(err); } const blobVal = Buffer.from(buffer).toString('base64') as unknown as Blob; const sizeVal = Buffer.byteLength(buffer); console.log('BLOB AND SIZE: ', blobVal, sizeVal); resolve({ blob: blobVal, pdfSize: sizeVal }); }); }); console.log('BLOB AND SIZE OUTSIDE: ', blob, pdfSize); await uploadFile(pdfId, blob as unknown as string, 'application/pdf'); // ...其余原有后续逻辑 } catch (error) { console.error(JSON.stringify(error, null, 2)); if (error instanceof Error) { throw new Error(error.message); } } },
修改后执行顺序会完全符合你的预期:先等PDF生成、blob和size赋值完成、打印回调内日志,再打印外层日志、执行上传逻辑。
补充:所有Node生态里参数为
(err, 返回值) => void形式回调的方法,默认都是异步非阻塞的,不要尝试在外层声明变量等回调赋值,要么把后续逻辑写在回调内,要么包装成Promise配合await使用。
内容的提问来源于stack exchange,提问作者SlothOverlord
相关产品推荐
相关产品推荐

