【发布时间】:2019-05-10 08:43:23
【问题描述】:
我正在尝试将数据库调用移出我的控制器以清理并使其可测试。当他们在控制器中时,一切都顺利进行。我将它们移出控制器并添加了异步以确保我们等待。否则,我会在Users.findOne() 的.exec() 中调用res.render() 函数。现在,一旦我使用 async/await,我的控制器中的函数会认为没有用户,因为它没有等待。
关于异步等待有几个关于 SO 的问题,但我没有找到一个可以解决我的问题的问题。我确实验证了我的用户已返回,并添加了控制台日志以显示路径。
- node mongoose async await 看起来很有希望,但他们的实际问题是未能退货,而我的退货很好
- async not waiting for await 是 kotlin 的问题
- async await not waiting 似乎非常适用,但我不完全理解关于嵌套等待/异步的答案 - 提问者遇到的问题比我的查询更复杂,因为他们正在处理循环和 forEach
- Javascript async await 是正确的,所以我检查了 mongoose 函数是否返回了一个承诺。 Mongoose 文档显示它已准备好异步,因为调用返回一个承诺。
假设我们正在解析路由/users
routes/index.js
// requires & other routes not shown
router.get('/users', controller.testUserShow);
控制器/index.js
// requires & other routes not shown
exports.testUserShow = async (req, res, next) => {
if (req.user) { // if code to get user is right here, with no async/await, the user is found and the code continues
try {
found = await services.fetchUser(req.user._id)
console.log("I am not waiting for at testusershow")
console.log(found); //undefined
// go on to do something with found
} catch(e) {
throw new Error(e.message)
}
}
}
services/index.js
const db = require('../db')
exports.fetchUser = async (id) => {
try {
console.log("fetchUser is asking for user")
return await db.returnUser(id)
} catch(e) {
throw new Error(e.message)
}
}
db/index.js
const User = require('../models/user');
exports.returnUser = async (id) => {
User.findById(id)
.exec(function(err, foundUser) {
if (err || !foundUser) {
return err;
} else {
// if this was in the controller
// we could res.render() right here
console.log("returnUser has a user");
console.log(foundUser); // this is a User
return foundUser;
}
});
}
控制台日志去
fetchUser is asking for user
I am not waiting for at testusershow
undefined
returnUser has a user
// not printed... valid user
如果我调用的东西没有返回承诺,我希望初始调用是未定义的,但 User.findOne() 应该。
我错过了什么?
【问题讨论】:
-
你的函数
returnUser实际上并没有返回任何东西。 -
通过
exec()调用,你可以传递一个回调函数,比如exec(cb)或者使用promise.exec().then(),听起来你需要使用后者。
标签: javascript asynchronous mongoose async-await