S3 Bucket图片URL无法从后端传至前端,疑为async/await问题
问题原因与解决方案:后端async/await导致前端无法获取file.imageUrl
核心问题
你遇到的问题确实和async/await的异步处理逻辑有关:forEach无法等待异步函数执行完成。
当你用forEach遍历note.files并执行异步操作时,forEach会立刻启动所有异步函数,但不会等待这些函数的Promise完成。代码会直接跳到res.json语句,此时所有给file.imageUrl赋值的操作还在后台运行,前端拿到的note对象里的files还没有被填充imageUrl值。
而当你换成同步赋值file.imageUrl = 'test'时,forEach里的同步代码会在res.json执行前全部完成,所以前端能正常拿到值。
修复方案
把forEach替换成Promise.all结合map,让代码等待所有异步操作完成后再发送响应:
const getNoteById = async (req, res, next) => { const noteId = req.params.id; let note; try { note = await Note.findById(noteId); } catch (err) { const error = new HttpError( `Something went wrong, could not find a note.`, 500 ); return next(error); } if (note.files.length) { // 用map生成所有异步操作的Promise,再用Promise.all等待全部完成 await Promise.all(note.files.map(async (file) => { const getObjectParams = { Bucket: bucketName, Key: file.name } const command = new GetObjectCommand(getObjectParams); const url = await getSignedUrl(s3, command, { expiresIn: 3600 }); file.imageUrl = url; console.log('file.imageUrl:', file.imageUrl); })); } if (!note) { const error = new HttpError( 'Could not find note for the provided id.', 404 ); return next(error); } res.json({ note: note.toObject({ getters: true }) }); };
原理说明
map会遍历数组,为每个file返回一个异步操作的Promise对象;Promise.all会等待所有Promise都执行完成后,才继续执行后续代码;- 加上
await后,res.json会在所有file.imageUrl赋值完成后再发送,前端就能拿到完整的files数据。
内容的提问来源于stack exchange,提问作者dawphin777
相关产品推荐
相关产品推荐

