【问题标题】:Execute nodejs synchronously同步执行nodejs
【发布时间】:2017-10-03 00:31:02
【问题描述】:

我正在尝试编写一个函数,该函数接受 mongodb 集合名称作为参数并返回集合的一个实例,以便它可以用于执行 CRUD 操作。但是,当我尝试返回集合的实例时,它会返回 'undefined',因为 return 语句在 MongoClient.connect 函数完成执行之前执行。

module.exports.dbConnection = function(collectionName)
{
  var MongoClient = require('mongodb').MongoClient;
  var url = "mongodb://127.0.0.1/test";
  var collName;
  MongoClient.connect(url, function(err, db) 
  {
      var collName = db.collection(collectionName); 
      console.log(collName)
  });
  return collName;
}

我可以就如何解决这个问题寻求帮助吗? 谢谢

【问题讨论】:

    标签: node.js mongodb asynchronous synchronous


    【解决方案1】:

    如果您至少使用 7.10 版本的 Node,您可以使用异步函数和 Promise 来完成此操作。

    // You can return a promise and resolve the promise once connected
    module.exports.dbConnection = function dbConnection(collectionName) {
      const MongoClient = require('mongodb').MongoClient;
      const url = "mongodb://127.0.0.1/test";
    
      return new Promise((resolve, reject) => {
        MongoClient.connect(url, function (err, db) {
          if (err) {
            return reject(err);
          }
          resolve(db.collection(collectionName)); 
        });
      });
    }
    
    // You can then call the function within an async function (Node v7.10 and above)
    async function fnThatCallsDbConnection() {
      try {
          const collName = await dbConnection('someCollection');
      } catch(e){
        // do something with error
      }
    }
    

    您可以做的其他事情是缓存您的数据库连接,这样您就不需要每次都连接 - 这是您可以做到的一种方法:

    let cachedDB;
    module.exports.dbConnection = function dbConnection(collectionName) {
      const MongoClient = require('mongodb').MongoClient;
      const url = "mongodb://127.0.0.1/test";
    
      return new Promise((resolve, reject) => {
        if (cachedDB) {
          resolve(cachedDB.collection(collectionName));
        } else {
          MongoClient.connect(url, function (err, db) {
            if (err) {
              return reject(err);
            }
            cachedDB = db;
            resolve(db.collection(collectionName)); 
          });
        }
      });
    }
    

    【讨论】:

    • 由于我对 nodejs 还很陌生,您能否在声明变量时告诉我 varlet 之间的区别。因为我看到你用过 let cachedDB;我们也可以使用 var cachedDB 吗?
    • 让我们定义一个块范围的局部变量 - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。是的,你可以在这里使用 var。
    【解决方案2】:

    完成此操作的正确方法是使用回调。接受一个回调参数,然后在操作完成时将所需的信息传递给该函数。

    module.exports.dbConnection = function(collectionName, cb)
    {
      var MongoClient = require('mongodb').MongoClient;
      var url = "mongodb://127.0.0.1/test";
      var collName;
      MongoClient.connect(url, function(err, db) 
      {
          var collName = db.collection(collectionName); 
          cb(collName); // invoke our callback
      });
    }
    

    你可以这样使用它:

    dbConnection('collName', function (coll) {
        console.log(coll);
        // do something else with our collection
    })
    

    【讨论】:

    • 谢谢,我有一个后续问题,每次调用 api 时打开连接有多理想?它会在数据库上产生开销吗?我该如何解决这个问题?
    猜你喜欢
    • 2018-07-29
    • 2018-07-09
    • 1970-01-01
    • 2017-11-14
    • 2018-07-24
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多