使用GridFS保存音频数据时文件ID返回同步问题求助
问题修复方案
你的核心问题是saveAudioToGridFS函数没有正确处理异步逻辑,导致无法返回文件ID。下面是具体修复步骤和代码:
1. 将saveAudioToGridFS包装为Promise
流操作是异步的,必须通过Promise封装,才能让调用端获取异步结果:
function saveAudioToGridFS(audioBlob) { // 返回Promise对象,包裹异步逻辑 return new Promise((resolve, reject) => { const gridFSBucket = new mongoose.mongo.GridFSBucket(conn.db), writeStream = gridFSBucket.openUploadStream(getAudioName()) // 监听流关闭事件,此时文件已完全写入GridFS writeStream.on('close', (file) => { console.log("saveAudioToGridFS.close-block") const fileId = writeStream.id.toString(); console.log("ID=", fileId) resolve(fileId); // 将文件ID传递给调用端 }); // 监听错误事件,传递错误信息 writeStream.on('error', (error) => { console.log("saveAudioToGridFS.error-block") reject(error); }); console.log("TRACE 1 : before createReadStream.") streamifier.createReadStream(audioBlob).pipe(writeStream) console.log("TRACE 2 : after createReadStream.") }); }
2. 在调用端使用await获取异步结果
路由回调已经是async函数,直接用await等待saveAudioToGridFS的结果即可:
server.post('/upload', async (req, res) => { try { if (!req.body.audio) { return res.status(400).json({message: 'No audio data uploaded.'}); } console.log("Before call to saveAudioToGridFS") const audioBuffer = Buffer.from(req.body.audio, 'base64'), // 用await等待Promise返回结果 fileId = await saveAudioToGridFS(audioBuffer); console.log("fileId=", fileId) // 现在能正确获取到文件ID了 // 创建新记录对象 const newRec = new AppCollectn({ channelID:req.body.channel, voiceRecordID:fileId, timeStamp: new Date().getTime() }); // 插入数据库 await newRec.save(); // 省略其他代码 res.json({fileId}); } catch (error) { console.error(error); res.status(500).json({ message: 'An error occurred during upload.', error: JSON.stringify(error) }); } });
修复说明
- 原代码中
resolve和reject没有绑定到任何Promise上下文,无法传递结果;包装成Promise后,这两个方法才有了正确的回调上下文。 - 流的
finish和close事件无需重复监听,close事件在文件元数据也写入完成后触发,更适合作为完成标志。 - 调用端用
await等待Promise完成,确保后续代码能拿到正确的fileId再执行。
内容的提问来源于stack exchange,提问作者Michel
相关产品推荐
相关产品推荐

