NodeJS提取通用异步函数后遇Pending Promise及空响应问题求助
问题解决步骤
核心问题分析
- 异步函数未正确等待:调用
getTimeFrames时没加await,导致拿到的是未完成的Promise对象,返回给前端会被序列化为空对象,控制台打印[Promise{<pending>}]。 - 循环提前返回:
getTimeFrames里的return语句放在循环内部,第一次循环就直接返回结果,后续的时间区间查询完全没执行。 - 错误处理不完整:
getTimeFrames的catch块仅打印错误,没有向上抛出,导致调用方无法捕获异常。
修正后的代码
1. 修复getTimeFrames函数
async function getTimeFrames(query, userId) { const day = "1 Day"; const week = "6 days → 1 week"; const month = "30 days → 1 Month"; const year = "365 days → 1 Year"; const total = "5000 days → Total"; try { const intervalFrame = [day, week, month, year, total]; let result = []; for (let i = 0; i < intervalFrame.length; i++) { const outputQuery = await poolPromise.query(query, [intervalFrame[i], userId]); outputQuery[0].forEach((item) => { item["interval_frame"] = intervalFrame[i]; }); // 移除循环内的return,改为累加结果 result = [...result, ...outputQuery[0]]; } // 循环结束后统一返回完整结果 return result; } catch (error) { console.error(error); // 抛出错误,让调用方的try-catch捕获处理 throw error; } }
2. 修复接口调用逻辑
router.get("/timeFrame/test", authenticateToken, async (req, res, next) => { const query = ` SELECT max(vocal_word.user_id) AS user_id, AVG(vocal_word.score) AS avg_score, SUM(vocal_word.score) AS sum_score, COUNT(*) AS total_inputs, min(vocal_word.\`date\`) AS oldest_date, max(vocal_word.\`date\`) AS newest_date, case when TIME(\`date\`) between '00:00:00' and '05:59:59' then 3 when TIME(\`date\`) between '06:00:00' and '09:29:59' then 8 when TIME(\`date\`) between '09:30:00' and '12:29:59' then 11 when TIME(\`date\`) between '12:30:00' and '15:29:59' then 14 when TIME(\`date\`) between '15:30:00' and '18:29:59' then 17 when TIME(\`date\`) between '18:30:00' and '23:59:59' then 20 end as 'time_intervals' FROM vocal_word WHERE \`date\` >= CURRENT_TIMESTAMP() - interval ? DAY AND vocal_word.user_id = ? GROUP BY time_intervals ORDER BY time_intervals ASC `; try { // 调用异步函数必须加await,等待Promise完成 const result = await getTimeFrames(query, req.user.userId); console.log(result); res.status(200).json(result); } catch (error) { // 统一处理异常,返回500错误或传递给错误中间件 res.status(500).json("Please contact back-end service"); // next(error); // 也可以选择传递给全局错误处理中间件 } });
关键修正点说明
- 添加
await:调用getTimeFrames时必须用await,确保拿到实际的查询结果而非Promise对象。 - 调整return位置:把return从循环内部移到循环结束后,保证所有时间区间的查询结果都被累加。
- 完善错误抛出:
getTimeFrames的catch块抛出错误,让接口的try-catch能捕获并处理,避免异常被静默忽略。 - 优化字符串拼接:把SQL查询用模板字符串(
)包裹,避免多行字符串的转义问题,可读性更好。
内容的提问来源于stack exchange,提问作者Momo
相关产品推荐
相关产品推荐

