Twitter克隆后端API向tweets数组push数据后响应仍为空是什么原因
问题根本原因
这是Node.js异步IO执行顺序导致的问题:
Tweet.find()是异步回调方法,循环中发起的所有数据库查询请求不会阻塞后续代码执行- for循环发起所有查询请求后,你直接调用了
res.json(),此时所有Tweet.find()的回调还没被触发,tweets数组还没被塞入数据,所以返回为空
修复代码示例
把回调写法改成async/await写法,等待所有数据库查询完成后再返回响应即可:
// 把路由处理函数改为async类型 app.get('/api/profile', auth, async function (req, res) { try { const email1 = req.user.email; // 等待关注列表查询完成 const followResults = await follower.find({ emailoffollowee: email1 }); const followers_data = followResults.map(d => d.emailoffollower); // 生成所有关注者的tweet查询 promise 列表 const tweetQueryPromises = followers_data.map(followerEmail => Tweet.find({ author: followerEmail })); // 等待所有tweet查询完成 const allTweetsResult = await Promise.all(tweetQueryPromises); // 把二维查询结果扁平化为一维数组 const tweets = allTweetsResult.flat(); res.json({ isAuth: true, id: req.user._id, email: req.user.email, name: req.user.firstname + req.user.lastname, followers: followers_data, tweet: tweets }); } catch (error) { console.log(error); res.status(500).json({ error: '服务器内部错误' }); } });
优化说明
- 用
Promise.all批量发起所有查询请求,比串行查询性能更高 - 统一用try/catch捕获所有异步操作的异常,避免服务崩溃
- 不需要手动遍历push数据,直接用数组的map、flat方法处理更简洁
内容的提问来源于stack exchange,提问作者Mahendra Kumar
相关产品推荐
相关产品推荐

