Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js Async/Await module export

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.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

// 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

like image 267
brocococonut Avatar asked Jul 02 '18 19:07

brocococonut


People also ask

Can you export async function in node JS?

This is not possible. Since the value is retrieved asynchronously, all modules that consume the value must wait for the asynchronous action to complete first – this will require exporting a Promise that resolves to the value you want.

What is module export in Nodejs?

Module exports are the instructions that tell Node. js which bits of code (functions, objects, strings, etc.) to export from a given file so that other files are allowed to access the exported code.

Can I use async await in node JS?

Async functions are available natively in Node and are denoted by the async keyword in their declaration. They always return a promise, even if you don't explicitly write them to do so. Also, the await keyword is only available inside async functions at the moment – it cannot be used in the global scope.

Is await blocking Nodejs?

See example below. Because await is only valid inside async functions and modules, which themselves are asynchronous and return promises, the await expression never blocks the main thread and only defers execution of code that actually depends on the result, i.e. anything after the await expression.


1 Answers

You have to export synchronously, so its impossible to export client and db directly. However you could export a Promise that resolves to client and 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

like image 192
Jonas Wilms Avatar answered Sep 24 '22 13:09

Jonas Wilms