最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - asyncawait is not working for mongo DB queries - Stack Overflow

programmeradmin0浏览0评论

Working case:

async await is working fine when we call a asynchronous function and that function returning a promise resolve()

Not working case:

async await is not working for mongo DB queries

tried then(), async/await

I have 2 JS files.

In one.js file i am importing function which is in functionone.js

WORKING CASE:

When one.js looks like

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

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

When one.js looks like

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

When functionone.js looks like

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])
    });
  });

Working case:

async await is working fine when we call a asynchronous function and that function returning a promise resolve()

Not working case:

async await is not working for mongo DB queries

tried then(), async/await

I have 2 JS files.

In one.js file i am importing function which is in functionone.js

WORKING CASE:

When one.js looks like

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

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

When one.js looks like

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

When functionone.js looks like

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])
    });
  });
Share Improve this question edited Jan 4, 2019 at 7:58 Erdogan Oksuz 62111 silver badges17 bronze badges asked Jan 4, 2019 at 5:57 user4743671user4743671 10
  • 1 In the second, functionone isn't returning anything, thus undefined – CertainPerformance Commented Jan 4, 2019 at 6:00
  • actually we are getting values in wallcheck[0] (in the second function) but code one.js is getting undefined eventhough we have values in wallcheck[0] – user4743671 Commented Jan 4, 2019 at 6:01
  • 1 Yes, because your functionone is not returning anything. – CertainPerformance Commented Jan 4, 2019 at 6:02
  • I understood that, but y is the question? – user4743671 Commented Jan 4, 2019 at 6:03
  • 1 It's not returning anything because you have no return statement in the function. Try using return to return the Promise. – CertainPerformance Commented Jan 4, 2019 at 6:04
 |  Show 5 more ments

2 Answers 2

Reset to default 6

Quick clarification:

  1. .collection('name') returns a Collection instance, not a Promise, so no need to await for it.
  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.

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().

Also, toArray(callback) does not take an async function as callback.

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.

Here we go

Case 1:

If it is a function which need to find documents and return from MongoDb as mihai mentioned, below answer is uber cool

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

case 2:

If there are nested functions which need to return values every time below ans will be the best as of my knowledge

-no need async/await keywords for every function or no need then()

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.

发布评论

评论列表(0)

  1. 暂无评论