Express+TypeScript中Multer上传CSV后返回空数组求助
问题解决:Express响应返回空数组的异步处理问题
你的问题核心是异步操作的执行顺序问题:newMember.save()是异步Promise操作,你在循环中直接调用它,但没有等待所有save操作完成就立即返回了响应。此时members和errors数组还未被填充,所以返回空数组;而控制台日志是在save的回调中打印的,那时候响应已经发出,数组才被填充。
以下是修复后的完整代码及关键说明:
步骤1:封装Multer上传为Promise
先将Multer的回调式上传转为Promise,便于用await等待操作完成:
const uploadPromise = (req: Request, res: Response): Promise<void> => { return new Promise((resolve, reject) => { upload(req, res, (err: any) => { if (!req.file) { reject(new Error("Please select file to be imported!")); } else if (err) { reject(new Error(`Error occurred while uploading file: ${err}`)); } else { resolve(); } }); }); };
步骤2:修改uploadFile函数,用Async/Await处理所有异步逻辑
//controller to import members exports.importMembers = async (req: Request, res: Response) => { try { await uploadFile(req, res); } catch (error: any) { return res.status(400).json({ status_code: 400, Error: error.message }); } }; //method to upload data const uploadFile = async (req: Request, res: Response) => { try { // 等待文件上传完成 await uploadPromise(req, res); const filePath = path.join("upload", req.file!.originalname); // 用await获取CSV解析结果,替代then回调 const source = await csvtojson().fromFile(filePath); // 收集所有成员保存的Promise const savePromises = source.map(row => { const member = { memberEnrollmentID: row["Member Enrollment ID"], name: row["Name"], dateOfBirth: row["Date Of Birth"], IDproofNumber: row["ID Proof Number"], email: row["Email"], phoneNumber: row["Phone Number"], address: row["Address"] }; const newMember = new Members(member); return newMember.save(); }); // 等待所有保存操作完成(无论成功/失败) const results = await Promise.allSettled(savePromises); // 整理成功和失败的结果 const members: {}[] = []; const errors: {}[] = []; results.forEach(result => { if (result.status === "fulfilled") { members.push(result.value); } else { errors.push(result.reason); } }); console.log(members.length); console.log(errors.length); return res.status(200).json({ status_code: 200, Members_Imported: members, Members_Rejected: errors }); } catch (error: any) { return res.status(400).json({ status_code: 400, Info: error.message }); } };
关键修复点说明
- Promise化Multer:避免回调嵌套,用
await确保文件上传完成后再执行后续逻辑。 - Await处理CSV解析:替代
then回调,让代码逻辑更线性,消除回调地狱。 - Promise.allSettled批量处理异步:收集所有成员保存的Promise,等待所有操作完成后再整理结果。这样能保证返回响应时,
members和errors数组已经被正确填充。 - 统一错误处理:将分散的错误逻辑集中到
try/catch中,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者paavan
相关产品推荐
相关产品推荐

