0

I have the following JS code

async function readAtlasAll() {
  return await MongoClient.connect(url, async function(err, db) {
    var dbo = db.db("Users");
    c = dbo.collection("List");
    r = await c.find({}).toArray();
    console.log(r);
    return r;
  });
}

console.log(readAtlasAll());

I'm not sure why, but printing the result of readAtlasAll() comes before printing the variable r inside the function, even though I'm awaiting the result of r beforehand. The terminal prints Promise { <pending> } first and afterwards prints the contents of r. I'm relatively new to JavaScript, so I would really appreciate the help. Thanks!

0

1 Answer 1

2

You cannot use both await and a plain callback on MongoDB API calls as the await won't do anything useful. Use one or the other, not both. This is because the MongoDB asynchronous APIs will return a promise if you do NOT pass a callback to them and you can then await that promise, but if you pass a callback, they do not return a promise, therefore the await does nothing useful at all. Here's how you would implement it by leaving out the callback and using await:

async function readAtlasAll() {
    const db = await MongoClient.connect(url);
    const dbo = db.db("Users");
    const c = dbo.collection("List");
    const r = await c.find({}).toArray();
    return r;          // this will be the resolved value of the returned promise
}

readAtlasAll().then(r => {
   console.log(r);
}).catch(err => {
    console.log(err);
});

Keep in mind that await has no magic powers at all. ALL it does is suspend execution of the function until a promise resolves/rejects. So, it only does anything useful when you await a promise.

And, further, ALL async functions return a promise so there is NO way to return an asynchronously-retrieved value directly from your function. You have to use an asynchronous mechanism for communicating back an asynchronously retrieved value such as a promise, a callback or an event. So readAtlasAll() can never return your value directly.

See How to return the response from an asynchronous call for more info on that.

Sign up to request clarification or add additional context in comments.

4 Comments

You can, it's just done differently.
@BGPHiJACK - I don't understand that comment. Feel free to write your own answer if you have a better way to write this code or provide a specific suggestion for me to improve this answer.
Your answer works but the question was to return an awaited result as a variable in JavaScript and this can in fact be done with callbacks and/or either both, it's not hard to introduce at all if necessary for the development.
@BGPHiJACK - There is NO way in Javascript to return an asynchronously retrieved value directly from this readAtlastAll() function such that the OP's console.log(readAtlasAll()); will show the result. If you think you have a way for console.log(readAtlasAll()); to show the result, please write an answer and show us. Javascript simply doesn't work that way with asynchronous operations. Yes, you could pass a callback into readAtlastAll(), but that's not returning the value from the function-that's the older mechanism for communicating asynchronous results which is in my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.