web-dev-qa-db-fra.com

Exportation du module Node.js Async / Await

Je suis un peu nouveau dans la création de modules et je me posais des questions sur module.exports et j'attendais que les fonctions asynchrones (comme une fonction mongo connect par exemple) pour terminer et exporter le résultat. Les variables sont correctement définies en utilisant async/wait dans le module, mais lorsque vous essayez de les enregistrer en exigeant le module, elles apparaissent comme non définies. Si quelqu'un pouvait m'orienter dans la bonne direction, ce serait formidable. Voici le code que j'ai jusqu'à présent:

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

Et voici le js qui nécessite le module

// test.js

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

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

Je suis assez familier avec js et j'apprends et étudie activement des choses comme asynchrone/attendre et aimer les fonctionnalités, mais oui ... Je ne peux pas vraiment le comprendre

4
brocococonut

Vous devez exporter de manière synchrone, il est donc impossible d'exporter client et db directement. Cependant, vous pouvez exporter une promesse qui se résout en client et db:

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

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

Vous pouvez donc l'importer en tant que:

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

(qui doit être lui-même dans une fonction asynchrone)

PS: console.error(err) n'est pas un gestionnaire d'erreur approprié, si vous ne pouvez pas gérer l'erreur, plantez simplement

3
Jonas Wilms

la solution fournie ci-dessus par @ Jonas Wilms fonctionne mais nécessite d'appeler requiert dans une fonction asynchrone chaque fois que nous voulons réutiliser la connexion. une autre manière consiste à utiliser une fonction de rappel pour renvoyer l'objet client 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}

alors nous pouvons utiliser la méthode mongoClient dans un fichier différent (route express ou tout autre fichier js).

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'});
};
0
Ofir Edi