Я как бы новичок в создании модулей и задавался вопросом о module.exports и ждал, пока асинхронные функции (например, функция mongo connect) завершатся и экспортируют результат. Переменные правильно определяются с помощью async / await в модуле, но при попытке зарегистрировать их, запрашивая модуль, они отображаются как undefined. Если бы кто-то мог указать мне правильное направление, было бы здорово. Вот код, который у меня есть:
// 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.info(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.info it from there
module.exports = {
client,
db
}
}
})(module)
А вот js, для которого требуется модуль
// test.js
const {client} = require('./module')
console.info(client) // Logs 'undefined'
Я довольно хорошо знаком с js и все еще активно изучаю и изучаю такие вещи, как async / await и подобные функции, но да ... я действительно не могу понять это



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы должны экспортировать синхронно, поэтому напрямую экспортировать client и db невозможно. Однако вы можете экспортировать обещание, которое разрешается в client и db:
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 рад помочь :)
Поскольку вы возвращаете функцию, этот подход откроет новое соединение для каждого требования. не так ли?
@elad нет, я возвращаю возвращаемое значение функции
Спасибо. Так что мне нужно требовать этого в каждой функции, которую я хочу запросить в БД? чувствовать себя очень "шаблонным"
@elad в каждом файле (/ module)
Как мы можем добиться того же для импорта es6 (import abc from 'sample-module')?
@DevAKS const abc = await import("./sample-module");
решение, предоставленное выше @Jonas Wilms, работает, но требует вызова асинхронной функции каждый раз, когда мы хотим повторно использовать соединение. альтернативный способ - использовать функцию обратного вызова для возврата клиентского объекта 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}
тогда мы можем использовать метод mongoClient в другом файле (экспресс-маршрут или любой другой файл 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.info(err);
return res.status(500).json({ error: err});
}
return res.status(201).json({ message: 'Student added'});
};
Это создаст несколько клиентов ... не уверен, что это необходимо. Также конечная точка API ответит ошибкой, если вы вызовете ее до загрузки клиента db.
Я использовал некоторые примеры кода из официального драйвера узла mongodb, чтобы проверить это. Но мне было бы полезно знать это в целом. Пример кода можно найти здесь