如何在NodeJS中配合async await使用fs模块解决接口提前返回问题
问题根因
你混淆了fs回调API和fs.promises Promise API的用法:fs.promises下的所有方法本身返回Promise,不需要传入回调函数。你给fs.promises.readFile传入了回调,此时该方法不会返回可被await等待的Promise,相当于异步读文件的逻辑没有被等待就直接走到后续返回响应的步骤,因此字段为空。
修复方案
- 移除
fs.promises.readFile的回调参数,直接用变量接收读文件返回的内容 - 文件读取的错误会直接被外层的
try/catch捕获,不需要在回调里单独处理 - 可以将同批次的3个文件读取改为
Promise.all并行执行,提升接口响应速度
修复后代码如下:
routerProgress.get("/see-first-last-progress", async (req, res) => { let infFront = { last_progress: {}, first_progress: {}, }; // 封装读取进度图片的公共方法,减少重复代码 const getProgressImgObj = async (singleProgress) => { const basePath = `${path}${dirname}`; // 并行读取三张图片,提升效率 const [front_img, side_img, back_img] = await Promise.all([ fs.promises.readFile(`${basePath}${singleProgress.dataValues.front_id}`), fs.promises.readFile(`${basePath}${singleProgress.dataValues.side_id}`), fs.promises.readFile(`${basePath}${singleProgress.dataValues.back_id}`) ]); return { weight: singleProgress.dataValues.weight, front_img, side_img, back_img, date: singleProgress.dataValues.date.toISOString().replace(/T/, " ").replace(/\..+/, "") } }; // 查询最新进度 try { const single_progress = await Progress.findOne({ where: { user_id: req.user.id }, order: [["date", "DESC"]], }); infFront.last_progress = await getProgressImgObj(single_progress); } catch (err) { if (err.code === 'ENOENT') { return res.send({ statusCode: "404", msg: "Photo not found" }); } return res.send({ statusCode: "500", msg: "An error occurred, please try again", }); } // 查询最早进度 try { const single_progress = await Progress.findOne({ where: { user_id: req.user.id }, order: [["date", "ASC"]], }); infFront.first_progress = await getProgressImgObj(single_progress); } catch (err) { if (err.code === 'ENOENT') { return res.send({ statusCode: "404", msg: "Photo not found" }); } return res.send({ statusCode: "500", msg: "An error occurred, please try again", }); } res.send({ statusCode: "200", data: infFront }); });
内容的提问来源于stack exchange,提问作者Gonsa02
相关产品推荐
相关产品推荐

