#node.js #mongodb #synchronous
#node.js #mongodb #синхронный
Вопрос:
Я пытаюсь вызвать какую-то функцию при synchronously
использовании node.js но согласно моему коду этого не происходит. Я объясняю свой код ниже.
viewDraggedFileContent = async(req, res) => {
try{
let id = req.params.id;
if(!id) {
responseObj = {
status: 'error',
msg: 'Please send the mongo id to fetch the file content.',
body: {}
};
res.send(responseObj);
}else{
let response = await findOne(id, 'useCaseFile');
console.log('res', response);
if(response['status'] === 0) {
responseObj = {
status: 'error',
msg: `Error occurred`,
body: response['data']
};
res.send(responseObj);
}else{
const resObj = [{
fileData: response.data.fileData,
_id: response['data']['_id']
}]
responseObj = {
status: 'success',
msg: `Fetched data successfully`,
body: resObj
};
res.send(responseObj);
}
}
}catch(error) {
console.log('Error::', error);
}
}
/**
* 1- Method to fetch single record from mongoDB as per _id.
*/
findOne = async (id, collName) => {
try{
let mongoID = new ObjectId(id);
MongoClient.connect(dbUrl, dbOptions).then(function (client) {
let connObj = client.db(dbName);
connObj.collection(collName).findOne({ _id: mongoID }, function (error, doc) {
if (error) {
client.close();
return {
status: 0,
data: error
};
} else {
client.close();
return {
status: 1,
data: doc
};
}
})
})
}catch(error){
console.log('Error while fetching single record::', error);
}
}
Здесь я вызываю findOne
функцию из viewDraggedFileContent
функции. Моя цель состоит в том, чтобы, как только требуемые данные вернутся из findOne
функции, они console.log('res', response);
должны выполняться, но в соответствии с моим кодом console.log('res', response);
выполняется до получения ответа от findOne
. Я также использовал async---await
, но все еще его запуск asynchronously
. Здесь мне нужно, чтобы после получения ответа от findOne
функции отобразилось сообщение консоли.
Ответ №1:
Вы можете использовать async/await
в функции findOne
async function findOne(id, collName) {
const client = await MongoClient.connect(url, {
useUnifiedTopology: true,
}).catch((err) => {
console.log("Error while connecting to db", err);
});
if (client) {
try {
let mongoID = new ObjectId(id);
let connObj = client.db(dbName);
let doc = await connObj.collection(collName).findOne({ _id: mongoID });
return {
status: 1,
data: doc,
};
} catch (error) {
console.log("Error while fetching single record::", error);
return {
status: 0,
data: error,
};
} finally {
client.close();
}
}
}
Комментарии:
1. он выдает эту
Error:: ReferenceError: client is not defined
ошибку.2. Извините за это. Я обновил ответ, пожалуйста, проверьте
Ответ №2:
Я думаю, что ваша проблема здесь в том, что вы не возвращаете обещание, поэтому строка, вызывающая вашу функцию findOne, ничего не ожидает.
Здесь два решения :
Когда вы передаете обратный вызов функции db.collection.findOne, она ничего не возвращает, но, если вы этого не сделаете, вы можете дождаться результата, например :
const doc = await connObj.collection(collName).findOne({ _id: mongoID })
Затем вы можете проанализировать свой документ и вернуть его.
Другое решение, если вернуть обещание в вашей функции findOne, а затем отправить ваш результат с разрешением, например :
findOne = async (id, collName) => {
return new Promise((resolve, reject) => {
try{
let mongoID = new ObjectId(id);
MongoClient.connect(dbUrl, dbOptions).then(function (client) {
let connObj = client.db(dbName);
connObj.collection(collName).findOne({ _id: mongoID }, function (error, doc) {
if (error) {
client.close();
reject(error);
} else {
client.close();
resolve(doc);
}
})
})
}catch(error){
console.log('Error while fetching single record::', error);
}
}
}
Тогда вам больше не нужен статус, и вы можете использовать then и catch для получения результата.