【问题标题】:Node.js Async/Await module exportNode.js 异步/等待模块导出
【发布时间】:2019-05-03 03:34:45
【问题描述】:

我对模块创建有点陌生,想知道 module.exports 并等待异步函数(例如 mongo 连接函数)完成并导出结果。在模块中使用 async/await 正确定义了变量,但是当尝试通过要求模块记录它们时,它们显示为未定义。如果有人能指出我正确的方向,那就太好了。这是我目前得到的代码:

// module.js

const MongoClient = require('mongodb').MongoClient
const mongo_host = '127.0.0.1'
const mongo_db = 'test'
const mongo_port = '27017';

(async module => {

  var client, db
  var url = `mongodb://${mongo_host}:${mongo_port}/${mongo_db}`

  try {
    // Use connect method to connect to the Server
    client = await MongoClient.connect(url, {
      useNewUrlParser: true
    })

    db = client.db(mongo_db)
  } catch (err) {
    console.error(err)
  } finally {
    // Exporting mongo just to test things
    console.log(client) // Just to test things I tried logging the client here and it works. It doesn't show 'undefined' like test.js does when trying to console.log it from there
    module.exports = {
      client,
      db
    }
  }
})(module)

这是需要模块的js

// test.js

const {client} = require('./module')

console.log(client) // Logs 'undefined'

我对 js 相当熟悉,并且仍在积极学习和研究诸如 async/await 和类似功能之类的东西,但是是的……我真的无法弄清楚这一点

【问题讨论】:

  • 我使用了一些来自 mongodb 官方节点驱动程序的示例代码来进行测试。但这对我一般来说很有用。示例代码可以找到here

标签: javascript node.js module async-await


【解决方案1】:

你必须同步导出,所以不可能直接导出clientdb。但是,您可以导出解析为 clientdb 的 Promise:

module.exports = (async function() {
 const client = await MongoClient.connect(url, {
   useNewUrlParser: true
 });

  const db = client.db(mongo_db);
  return { client, db };
})();

那么你可以将它导入为:

const {client, db} = await require("yourmodule");

(必须在异步函数本身中)

PS:console.error(err) 不是一个合适的错误处理程序,如果你不能处理错误就崩溃

【讨论】:

  • 啊,我明白了。最后我将导出需要 mongo 连接的东西,而不是导出连接本身。不过这确实有道理,谢谢:)
  • @brocococonut 很高兴为您提供帮助 :)
  • 因为您返回一个函数,该方法将为每个需求打开一个新连接。不是吗?
  • 谢谢。所以我需要在我想查询数据库的每个函数中都需要这个?感觉很“样板”
  • @DevAKS const abc = await import("./sample-module");
【解决方案2】:

@Jonas Wilms 上面提供的解决方案正在运行,但每次我们想要重用连接时都需要在异步函数中调用 requires。另一种方法是使用回调函数返回 mongoDB 客户端对象。

mongo.js:

const MongoClient = require('mongodb').MongoClient;

const uri = "mongodb+srv://<user>:<pwd>@<host and port>?retryWrites=true";

const mongoClient = async function(cb) {
    const client = await MongoClient.connect(uri, {
             useNewUrlParser: true
         });
         cb(client);
};

module.exports = {mongoClient}

然后我们可以在不同的文件(快速路由或任何其他 js 文件)中使用 mongoClient 方法。

app.js:

var client;
const mongo = require('path to mongo.js');
mongo.mongoClient((connection) => {
  client = connection;
});
//declare express app and listen....

//simple post reuest to store a student..
app.post('/', async (req, res, next) => {
  const newStudent = {
    name: req.body.name,
    description: req.body.description,
    studentId: req.body.studetId,
    image: req.body.image
  };
  try
  {

    await client.db('university').collection('students').insertOne({newStudent});
  }
  catch(err)
  {
    console.log(err);
    return res.status(500).json({ error: err});
  }

  return res.status(201).json({ message: 'Student added'});
};

【讨论】:

  • 这将创建多个客户端...不确定是否需要。如果您在加载 db 客户端之前调用它,API 端点也会响应错误。
猜你喜欢
  • 2019-10-28
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 2019-04-22
  • 2019-01-15
  • 1970-01-01
  • 2019-11-17
相关资源
最近更新 更多