Невозможно вызвать функции синхронным способом, используя node.js и mongodb

#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 для получения результата.