Home > Enterprise >  How do I fetch data out of mongodb out of an async function?
How do I fetch data out of mongodb out of an async function?

Time:09-29

I am relatively new to JavaScript and especially new to promise. I am struggling to get the second console.log() to output the same as the first one. Is this even possible? Do I have to do all of my code using that uses the kittens data inside of the async function?

  async function getKittens() {
    const kittens = await Kitten.find();
    console.log(kittens);
    return(kittens)
  }
  console.log(getKittens());

When this is ran I get (the promise is from the console.log() outside of the async function.

Promise { <pending> }
[
  {
    _id: new ObjectId("633499451739979630b645be"),
    name: 'Silence',
    __v: 0
  },
  {
    _id: new ObjectId("6334998b51a957972355eb63"),
    name: 'Silence',
    __v: 0
  }
]

CodePudding user response:

All, async functions return a promise so the caller of your function needs to use await or .then() to get the final result. This is because the async function returns a promise as soon as your function hits its first await. The result is not known yet when the function returns.

There is no magic way to turn an asynchronously retrieved value into a synchronously retrieved value, even with await. And no way to directly return from your function the asynchronously retrieved value. The function will return before the value is known.

If you're retrieving the value asynchronously, then anyone using that value outside of your function will have to use await or .then() to get access to the value.

async function getKittens() {
  const kittens = await Kitten.find();
  console.log(kittens);
  return(kittens)
}

getKittens().then(kittens => {
    console.log(kittens);
}).catch(err => {
    console.log(err);
});

To understand the timing of things a little better, if you insert these diagnostic messages:

async function getKittens() {
  console.log("in getKittens()");
  const kittens = await Kitten.find();
  console.log("after await Kitten.find()");
  return(kittens)
}

console.log("about to call getKittens()");    
let p = getKittens();
console.log("after calling getKittens()");
p.then(kittens => {
    console.log("got result from getKittens()");
}).catch(err => {
    console.log(err);
});

You will see this in the console:

about to call getKittens()
in getKittens()
after calling getKittens()
after await Kitten.find()
got result from getKittens()

Note that the function has returned BEFORE the await has finished and before the result of Kitten.find() is known.

CodePudding user response:

I don't think there is a way to access this data outside of an async function so my solution is to wrap the whole thing in an async.

   (async () => {
      const kittens = await Kitten.find();
       console.log(kittens);
   })();
  • Related