Nodejs和MongoDB:无法从函数返回值

时间:2017-09-02 17:09:43

标签: node.js mongodb

var config = require('config.json');
var mongo = require('mongoskin');
var db = mongo.db(config.connectionString, { native_parser: true });

module.exports.getNextSequence =  function (name) {
    var temp;
    db.collection("counters").findAndModify(
        { _id: name },           // query
        [],                      // represents a sort order if multiple matches
        { $inc: { seq: 1 } },    // update statement
        { new: true },           // options - new to return the modified document
        function (err, doc) {
            temp = doc.value.seq;
            console.log(temp);   // <-- here the temp is getting printed correctly
        }
    );
    return temp; 
}

使用上面的代码,我无法返回doc.value.seq的值。在执行console.log(obj.getNextSequence)时,它会打印undefined

我希望函数返回doc.value.seq的值。

2 个答案:

答案 0 :(得分:1)

我不熟悉mongoskin,所以我不肯定这是正确的,但数据库查询通常是异步的,因此您需要通过回调访问查询的值。

我猜你的“getNextSequence”函数在数据库查询完成之前(即在“temp = doc.value.seq”语句之前)返回“temp”变量。

尝试这样的事情:

module.exports.getNextSequence =  function (name, callback) {
    var temp;
    db.collection("counters").findAndModify(
        { _id: name },           // query
        [],                      // represents a sort order if multiple matches
        { $inc: { seq: 1 } },    // update statement
        { new: true },           // options - new to return the modified document
        function (err, doc) {
            temp = doc.value.seq;
            callback(temp);
        }
    );
}

然后从传递给getNextSequence的回调中访问“temp”。

答案 1 :(得分:1)

findAndModify是一个异步函数。您的console.log行会在之后运行<{1}},因此会tempundefined。为了使其工作,您将需要使用自己的异步方法。在您的情况下,有两种可用的方法。

Callbacks

您已经在使用回调,并将其作为findAndModify的最终参数提供。您可以扩展此方法并将其提供给您自己的回调,如下所示:

module.exports.getNextSequence =  function (name, callback) {
    db.collection("counters").findAndModify(
        { _id: name },
        [],
        { $inc: { seq: 1 } },
        { new: true },
        function (err, doc) {
            if (err) {
                return callback(err);
            }

            callback(null, doc.value.seq);
        }
    );
}

当然,这需要您将回调传递给getNextSequence并遵循上游的回调模式。您可能还希望处理来自mongoskin的错误并对您自己的错误进行处理。

Promises

如果您没有向findAndModify提供回叫,它将返回一个承诺,您可以链接到该承诺,如下所示:

module.exports.getNextSequence =  function (name) {
    return db.collection("counters").findAndModify(
        { _id: name },
        [],
        { $inc: { seq: 1 } },
        { new: true }
    ).then(function (doc) {
        return doc.value.seq;
    });
}

同样,这将要求您遵循上游的承诺模式。如果你选择这种方法,你会想要阅读承诺,这样你就可以正确处理错误,我在上面的例子中没有提到过。