2017-09-02 129 views
2
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; 
} 

使用上面的代码返回值,我无法返回的​​值。在执行console.log(obj.getNextSequence)时,它会打印undefined的NodeJS和MongoDB:无法从功能

我想函数返回值​​。

回答

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回调中访问 “温度”。

1

findAndModify异步函数。您的console.log行将在之后运行,您将返回temp,因此将为undefined。为了得到这个工作,你需要使用你自己的异步方法。在你的情况下有两种可用的方法。

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; 
    }); 
} 

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