简体   繁体   English

async / await不适用于mongo数据库查询

[英]async/await is not working for mongo DB queries

Working case: 工作案例:

async await is working fine when we call a asynchronous function and that function returning a promise resolve() 当我们调用一个异步函数并且该函数返回一个promise resolve()时async await工作正常

Not working case: 不工作案例:

async await is not working for mongo DB queries async await不适用于mongo数据库查询

tried then(), async/await 尝试了then(),async / await

I have 2 JS files. 我有2个JS文件。

In one.js file i am importing function which is in functionone.js 在one.js文件中,我正在导入functionone.js中的函数

WORKING CASE: 工作案例:

When one.js looks like 当one.js看起来像

var functiononestatus = transactions.functionone(req.session.email).then((came) => {
  console.log(came); // getting `need to be done at first` message
  console.log("exec next")
});

When functionone.js looks like 当functionone.js看起来像

module.exports.functionone = functionone;

async function functionone(email) {
  return await new Promise((resolve, reject) => {
    resolve('need to be done at first')
  });
});

NOT WORKING CASE (when mongo db query need to be executed): 不工作的情况(当需要执行mongo db查询时):

When one.js looks like 当one.js看起来像

var functiononestatus = transactions.functionone(req.session.email).then((came) => {
  console.log(came); // getting undefined
  console.log("exec next")
});

When functionone.js looks like 当functionone.js看起来像

module.exports.functionone = functionone;

async function functionone(email) {

  //mongo starts
  var collection = await connection.get().collection('allinonestores');
  await collection.find({
    "email": email
  }).toArray(async function(err, wallcheck) {
    return await new Promise((resolve, reject) => {
      resolve(wallcheck[0])
    });
  });

Quick clarification: 快速澄清:

  1. .collection('name') returns a Collection instance, not a Promise, so no need to await for it. .collection('name')返回一个Collection实例,而不是Promise,所以不需要await它。
  2. toArray() operates in two modes: either with a callback when a function is provided, either returns a Promise when no callback function is provided. toArray()以两种模式运行:在提供函数时使用回调,或者在没有提供回调函数时返回Promise。

You're essentially expecting a Promise result out of toArray() while supplying a callback function, resulting in undefined , because callback takes priority and no promise is returned, due to the dual operation mode of toArray(). 在提供回调函数时,你实际上期望toArray()的Promise结果,导致undefined ,因为toArray()的双重操作模式,回调优先并且不返回promise。

Also, toArray(callback) does not take an async function as callback. 此外, toArray(callback)不会将async函数作为回调。

Here's how your code should look like, for retrieving a collection: 以下是代码的样子,用于检索集合:

const client = await MongoClient.connect('your mongodb url');
const db = client.db('your database name'); // No await here, because it returns a Db instance.
const collection = db.collection('allinonestores'); // No await here, because it returns a Collection instance.

and then, code for fetching results: 然后,获取结果的代码:

const db = <get db somehow>;

// You could even ditch the "async" keyword here,
// because you do not do/need any awaits inside the function.
// toArray() without a callback function argument already returns a promise.
async function functionOne(email) {

  // Returns a Collection instance, not a Promise, so no need for await.
  const collection = db.collection('allinonestore');

  // Without a callback, toArray() returns a Promise.
  // Because our functionOne is an "async" function, you do not need "await" for the return value.
  return collection.find({"email": email}).toArray();
}

and code alternative, using callback: 和代码替代,使用回调:

const db = <get db somehow>;

// You could even ditch the "async" keyword here,
// because you do not do/need any awaits inside the function.
// You're forced to return a new Promise, in order to wrap the callback
// handling inside it
async function functionOne(email) {

  // Returns a Collection instance, not a Promise, so no need for await.
  const collection = db.collection('allinonestore');

  // We need to create the promise outside the callback here.
  return new Promise((resolve, reject) => {
    db.find({"email": email}).toArray(function toArrayCallback(err, documents) {
       if (!err) {
         // No error occurred, so we can solve the promise now.
         resolve(documents);
       } else {
         // Failed to execute the find query OR fetching results as array someway failed.
         // Reject the promise.
         reject(err);
       }
    });
  });
}

Note: First of all i really need to thank @mihai Potra for the best answer. 注意:首先,我真的要感谢@mihai Potra的最佳答案。

Here we go 开始了

Case 1: 情况1:

If it is a function which need to find documents and return from MongoDb as mihai mentioned, below answer is uber cool 如果它是一个需要查找文件并从MongoDb返回的功能,如下所述,下面的回答非常酷

const db = <get db somehow>;
async function functionOne(email) {
  const collection = db.collection('allinonestore');
  return collection.find({"email": email}).toArray();
}

case 2: 案例2:

If there are nested functions which need to return values every time below ans will be the best as of my knowledge 如果有嵌套函数需要在每次下面返回值,那么根据我的知识,ans将是最好的

-no need async/await keywords for every function or no need then() - 不需要每个函数的async / await关键字或者不需要()

function one(<parameter>) {
return new Promise(function(resolve, reject) {
const collection = connection.get().collection('<collection_name>');
const docs = collection.find({"Key": Value_fromFunction}).toArray( function (err, result) {
resolve(result[0]);
});

That's it, use resolve callback when ever it needed. 就是这样,在需要时使用resolve回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM