javascript Node.js 异步/等待模块导出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51142495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 09:25:47  来源:igfitidea点击:

Node.js Async/Await module export

javascriptnode.jsmoduleasync-await

提问by brocococonut

I'm kinda new to module creation and was wondering about module.exports and waiting for async functions (like a mongo connect function for example) to complete and exporting the result. The variables get properly defined using async/await in the module, but when trying to log them by requiring the module, they show up as undefined. If someone could point me in the right direction, that'd be great. Here's the code I've got so far:

我对模块创建有点陌生,想知道 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)

And here's the js that requires the module

这是需要模块的js

// test.js

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

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

I'm fairly familiar with js and am still actively learning and looking into things like async/await and like features, but yeah... I can't really figure that one out

我对 js 相当熟悉,并且仍在积极学习和研究诸如 async/await 和类似功能之类的东西,但是是的...我真的想不通

回答by Jonas Wilms

You have to export synchronously, so its impossible to export clientand dbdirectly. However you could export a Promise that resolves to clientand db:

你必须同步输出,所以它不可能出口clientdb直接。但是,您可以导出解析为client和的 Promise db

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

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

So then you can import it as:

那么你可以将它导入为:

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

(that has to be in an async function itself)

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

PS: console.error(err)is not a proper error handler, if you cant handle the error just crash

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

回答by Ofir Edi

the solution provided above by @Jonas Wilms is working but requires to call requires in an async function each time we want to reuse the connection. an alternative way is to use a callback function to return the mongoDB client object.

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

mongo.js:

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}

then we can use mongoClient method in a diffrent file(express route or any other js file).

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

app.js:

应用程序.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'});
};