javascript - 为什么我的异步函数返回一个空数组?
问题描述
我试图通过将用户推送到数组中并返回该数组来获取用户的匹配项,以便我的路由器可以将数据发送到前端。但是我的异步函数有一个问题:我只有一个空数组。我试图设置一些断点,我注意到我的路由器在我的服务将数据推送到数组之前发送了数据。
这是我的路由器代码:
router.get("/allMatchs", auth, async (req, res) => {
const user = await userService.getUserById(req);
const matchs = await service.getMatchsByUser(user);
res.send(matchs);
});
还有我的服务代码:
async function getMatchsByUser(user) {
const userMatchs = user.matchs;
let matchs;
await userMatchs.map(async (m) => {
let match = await Match.findById(m._id).select([
"-isConfirmed",
"-isUnmatched",
]);
matchs.push(match);
});
return matchs;
}
感谢您的帮助。
解决方案
是因为.map()
没有async
觉知。它不会等待回调返回的承诺。所以,当你这样做时:
await userMatchs.map(...)
.map()
返回一个数组。您正在对一系列承诺调用 await (请记住,.map()
返回一个数组)。那没有任何用处。它不等待任何东西,内部的各个迭代.map()
也没有等待。
您可以切换到普通for
循环,因为for
循环是 promise 感知的并且它会await
正确,或者您可以使用await Promise.all(userMatchs.map(...))
.
你可以这样做:
function getMatchsByUser(user) {
return Promise.all(user.matchs.map((m) => {
return Match.findById(m._id).select([
"-isConfirmed",
"-isUnmatched",
]));
});
}
或者,如果您想一次按顺序对数据库执行一个请求,请使用一个普通for
循环,该循环await
适用于:
async function getMatchsByUser(user) {
let matchs = [];
for (let m of user.matchs) {
let match = await Match.findById(m._id).select([
"-isConfirmed",
"-isUnmatched",
]);
matchs.push(match);
}
return matchs;
}
推荐阅读
- javascript - 对参数化 HTML 元素访问处理的建议
- python - 根据第二个 DF 中标识的特定列的平均值创建新的 DF 列
- python - 将机器学习模型应用于另一个数据集
- javascript - 从异步函数返回的承诺可以被垃圾收集吗?
- visual-studio-code - 不同的选项卡大小取决于我在 VS Code 中编程的语言/文件
- ubuntu-20.04 - fail2ban 不阻止 IP
- python - Python Azure Function 远程调试
- html - 标签转到新页面,但没有转到新页面的顶部
- java - 测试时无法从 yml 文件中读取值
- django - celery app.delay() 一直在等待响应,不工作