NodeJS Express接口返回空对象问题排查(实际数据非空)
问题排查与修复方案
核心问题1:Map.values()无法被Express正确序列化
Express的res.send()无法直接将Map的Iterator对象序列化为JSON,因此返回空对象。控制台能打印是因为Node.js控制台会自动遍历Iterator并展示内容,但JSON序列化时不支持这种类型。
修复:
将Map的values转为数组后再返回:
// 替换原res.send语句 res.send(Array.from(map_.values()));
核心问题2:groupByBookings中存在多余await与逻辑错误
- 不必要的await:
pool.execute()的结果已在处理器函数中通过await获取,bookings[0]是普通数组,无需再用await包裹数组长度或元素访问,多余的await会导致无意义的异步等待。 - 分组判断错误:原代码用
map_.has(current.id)判断,但解构字段中只有bookingid,不存在id,这会导致所有数据都走新建Map条目的分支,无法正确分组。 - 变量未声明:
newObj未用let/const声明,会成为全局变量,存在泄漏风险。
修复后的groupByBookings:
function groupByBookings(bookings) { let map_ = new Map(); for (let i = 0; i < bookings[0].length; i++) { let current = bookings[0][i]; let { bookingid, venueid, userid, bookingtimestamp, bookingstatus, paymenttype, price, timeslotstart, timeslotend, noofcourts, } = current; // 修正为用bookingid判断 if (map_.has(bookingid)) { map_.get(bookingid).slots.push({ timeslotstart, timeslotend }); } else { // 声明变量避免全局泄漏 const newObj = { bookingid, venueid, userid, bookingtimestamp, bookingstatus, paymenttype, price, noofcourts, }; newObj.slots = [{ timeslotstart, timeslotend }]; map_.set(bookingid, newObj); } } return map_; }
额外优化:移除groupByBookings的async关键字
函数内部已无异步操作,去掉async可避免不必要的Promise包装。
最终修复后的处理器函数
async function handleGetAllBookingByUserId(req, res, next) { try { const bookings = await pool.execute(queries.getAllBookingByUserId, [req.params.userId]); const map_ = groupByBookings(bookings); console.log(map_.values()); res.send(Array.from(map_.values())); } catch (err) { next(err); } }
内容的提问来源于stack exchange,提问作者HighSha
相关产品推荐
相关产品推荐

