同步猫鼬请求

时间:2017-01-16 12:59:35

标签: node.js mongodb asynchronous mongoose ecmascript-7

是否可以在函数上下文中处理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 )以及其他所有东西都可以用来解决问题而不需要嵌套。

提前谢谢。

2 个答案:

答案 0 :(得分:4)

有两点错误:

  • 不能同步调用Mongoose方法(无论如何,同步调用数据库根本不是一个好主意。)
  • 也不能在ES6类的构造函数中使用async / await和generators。在answer
  • 中对此进行了解释

如果你不想要嵌套代码,一个简单的选择就是使用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")
          }
        }
      });
    })    
}