在函数

时间:2016-01-10 06:09:34

标签: node.js mongoose

这里是Node和Mongoose的新手。我在函数中以同步方式运行我的mongoose findOne()查询时遇到问题。这是我的代码:

exports.read = function(req, res){
    console.log("in articles controller read()");

        //try to get article creatorId and use user providerData
        //name to make fullName
        var userName = "";

        //get article creator id
        User.findOne({ '_id': req.article.creator._id }, function(err, person){
            if(err) { return next(err)};
            if (!person) { return next(new Error('Failed to find user'))};

            console.log("found person");
            //return providerData name 
            userName =  person.providerData.name;


        });

        //assign username value to article creator
        var splitName = userName.split(' ');
        req.article.creator.fullName = userName;
        req.article.creator.firstName = splitName[0] || '';
        req.article.creator.lastName = splitName[1] || '';

    console.log("end of read()";
    res.json(req.article);
};

当我查看我的控制台时,我希望按以下顺序查看日志:

    文章控制器read() 中的
  1. 找人
  2. read()
  3. 的结尾

    但相反,我在控制台中看到了:

      文章控制器read() 中的
    1. read()
    2. 的结尾
    3. 找人
    4. 我假设这个问题可能与节点的异步性有关吗? 基本上,我想在为我的req对象赋值之前运行findOne()查询,这样我实际上可以分配一些东西。请帮忙。

2 个答案:

答案 0 :(得分:1)

回调是异步的,您需要在其中移动代码。

User.findOne({ '_id': req.article.creator._id }, function(err, person){
    if(err) { return next(err)};
    if (!person) { return next(new Error('Failed to find user'))};

    console.log("found person");
    //return providerData name 
    userName =  person.providerData.name;

    //assign username value to article creator
    var splitName = userName.split(' ');
    req.article.creator.fullName = userName;
    req.article.creator.firstName = splitName[0] || '';
    req.article.creator.lastName = splitName[1] || '';

    res.json(req.article);
});

答案 1 :(得分:0)

您正在使用asynchronous和事件驱动的Nodej。 所以它会按顺序调用方法:

console.log("in articles controller read()");
User.findOne();
console.log("end of read()";
  

但是User.findOne是数据库调用很慢,所以它调用User.findOne然后它会进行另一个方法调用,当它们返回结果时它会打印出来。

你将获得结果

  

在文章控制器中读取()
  阅读结束()
  找到了人

要解决此问题,您可以使用async.js,也可以直接将值放在findOne结果中:

    exports.read = function(req, res){
    console.log("in articles controller read()");

        //try to get article creatorId and use user providerData
        //name to make fullName
        var userName = "";

        //get article creator id
        User.findOne({ '_id': req.article.creator._id }, function(err, person){
            if(err) { return next(err)};
            if (!person) { return next(new Error('Failed to find user'))};

            console.log("found person");
            //return providerData name 
            userName =  person.providerData.name;

            //assign username value to article creator
            var splitName = userName.split(' ');
            req.article.creator.fullName = userName;
            req.article.creator.firstName = splitName[0] || '';
            req.article.creator.lastName = splitName[1] || '';

            console.log("end of read()");
            res.json(req.article);

        });
    }