我正在尝试将数据库调用移出控制器,以清理并使其可测试。当它们在控制器中时,一切都会顺利进行。我将它们移出了控制器,并添加了一个异步以确保我们等待。否则,我将在res.render()
的{{1}}中调用.exec()
函数。现在,一旦我使用了异步/等待,控制器中的功能就会认为没有用户,因为它没有在等待。
SO上有几个关于异步等待的问题,但是我没有找到解决我的问题的方法。我确实验证了返回的用户,并添加了控制台日志以显示路径。
假设我们正在解决路线Users.findOne()
routes / index.js
/users
controllers / index.js
// requires & other routes not shown
router.get('/users', controller.testUserShow);
services / 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)
}
}
}
db / 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)
}
}
控制台日志消失
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
应该是未定义的,则初始调用是不确定的。
我在这里想念什么?
答案 0 :(得分:4)
这是最简单的方法:
const User = require('../models/user');
exports.returnUser = (id) => {
return User.findById(id).exec().then(foundUser => {
console.log(foundUser); // this is a User
return foundUser;
});
}
如果要使用异步/等待,则可以执行以下操作:
exports.returnUser = async id => {
const foundUser = await User.findById(id).exec();
console.log({foundUser});
return foundUser;
});
}
,如果您想使用回调,则如下所示:
exports.returnUser = (id, cb) => {
return User.findById(id).exec(cb);
}
关于Mongoose的很酷的想法是,如果不传递回调,它将从exec函数/方法中返回一个Promise。
答案 1 :(得分:1)
您的db/index
应该是这样的:
exports.returnUser = (id) => {
return User.findById(id);
}
当您不致电exec时,它将返回一个承诺。并且由于您的services/index.js
已经使用await
来获取响应,因此db/index
不必是异步函数。