是否可以在函数上下文中处理db.model.find()
查询并使用回调和承诺使用mongoose库检索结果而不?
我需要放心,如果某个用户在运行控制器的过程中存在,那么,由于大量相同的操作(例如,与数据库的通信),我无法将当前范围最小化到回调。此外,我正在尝试在我的项目中实现MVC模型,因此,我希望将帮助程序库(模块)保存在单独的文件中。这就是为什么我不想使用任何回调或承诺 - 它们会使事情复杂化甚至更多事情。
<小时/> 例如,我应该如何重写以下代码才能成功执行(如果实际可行)(您可以忽略登录模型和控制器 - 如果使用回调重写该代码,则编写它们以表示复杂性) :
user.js lib
var db = require('./lib/db');
class User{
constructor(id){ //get user by id
var result = db.models.user.findOne({_id: id}); //unsupported syntax in real :(
if(!result || result._id != _id)
return false;
else{
this.userInfo = result;
return result;
}
}
}
module.exports = User;
登录模式
var user = require('./lib/user')
var model = {};
model.checkUserLogged(function(req){
if(!req.user.id || req.user.id == undefined)
return false;
if(!(this.user = new user(req.user.id)))
return false;
else
return true;
});
module.exports = model;
登录控制器
var proxy = require('express').router();
proxy.all('/login', function(req, res){
var model = require('./models/login');
if(!model.checkUserLogged()){
console.log('User is not logged in!');
res.render('unlogged', model);
}else{
console.log('User exists in database!');
res.render('logged_in', model);
}
});
生成器函数/产量,async / await( es2017 )以及其他所有东西都可以用来解决问题而不需要嵌套。
提前谢谢。答案 0 :(得分:4)
有两点错误:
如果你不想要嵌套代码,一个简单的选择就是使用async / await(目前在Node.js中可以使用标志,不推荐用于生产)。由于Mongoose方法返回promise,因此可以与async / await一起使用。
但正如我所说,你不能在构造函数中这样做,所以它必须在其他地方。
举个例子,你可以这样做:
var proxy = require('express').router();
var db = require('./lib/db');
proxy.all('/login', async function(req, res){
const result = await db.models.user.findOne({_id: req.user.id}).exec();
if (!result) {
console.log('User is not logged in!');
return res.render('unlogged');
}
res.render('logged_in');
});
答案 1 :(得分:0)
古老的问题,但我想分享一种处理方法,这在我最初的几次搜索中都没有发现。
我想从模型中获取数据,运行一些逻辑并从该逻辑返回结果。我需要对模型调用进行承诺包装。
下面是一个稍微抽象的函数,该函数采用一个模型来运行mongoose / mongo查询,并提供几个参数来帮助它执行一些逻辑。然后,它将返回承诺或拒绝中期望的值。
export function promiseFunction(aField: string, aValue, model: Model<ADocument, {}>): Promise<aType> {
return new Promise<string>((resolve, reject) => {
model.findOne({[aField]: aValue}, (err, theDocument) => {
if(err){
reject(err.toString());
} else {
if(theDocument.someCheck === true){
return(theDocument.matchingTypeField)
} else {
reject("there was an error of some type")
}
}
});
})
}