try/catch块中函数未完成时提前执行document.save()与res.redirect问题
问题根因
- 混用了回调式API和
async/await异步逻辑,现有代码执行顺序完全不符合预期:s3.getObject传入回调时返回值不是Promise,外层的await不会等待回调执行,try/catch也无法捕获回调内抛出的错误apiInstance.convertDocumentPptxToPng是回调式异步方法,调用后不会阻塞后续代码执行,还没等回调返回生成的URL,就已经执行了course.save()和重定向逻辑,自然存入的数组为空
修复方案
用Node.js内置的util.promisify将所有回调式API转为Promise风格,再通过async/await控制执行顺序:
- 首先引入promisify工具
const { promisify } = require('util')
- 将回调式方法转为Promise版本
// 转换s3.getObject const getS3Object = promisify(s3.getObject.bind(s3)) // 转换PPT转PNG方法 const convertPptxToPng = promisify(apiInstance.convertDocumentPptxToPng.bind(apiInstance))
- 改写逻辑为全async/await风格,确保所有异步操作按顺序执行
try { const params = { Bucket: 'bucket', Key: req.file.key } // 等待s3文件读取完成 const data = await getS3Object(params) const inputFile = Buffer.from(data.Body) // 等待格式转换完成,获取转换结果(原来callback里拿到的返回值会在这里返回) const convertResult = await convertPptxToPng(inputFile) // 此处替换为原来callback里给course的URL数组赋值的逻辑,按实际返回结构修改即可 course.urlArray = convertResult.urls // 全部逻辑执行完成后再保存、重定向 await course.save() res.redirect('/course/admin') } catch(err) { console.log(err) // 可自行补充错误场景的返回逻辑,避免请求挂起 }
内容的提问来源于stack exchange,提问作者devFromAbove
相关产品推荐
相关产品推荐

