Question about returns in asynchronous function

I recently learned about Async/Await but it is confusing to me when we can be sure that the promise of an async function is resolved.

For example, let us say that I have the function:

    async function getBankDetailsAsync(id) {
          let bankDetails = await Customer.find({_id: id});
          return bankDetails;
    }
  
    let id = "345";
    let bankDetailsForId = getBankDetailsAsync(id);
    console.log(bankDetailsForId);

Can we be sure that bankDetailsForId is acquired before we print it?

Also, in my code, I might do another database operation using information from a database in the same function. Does that mean I should use getBankDetailsAync(id).then() rather than await and put all the code after the database read inside the then function?

If you await the promise of an async function, you can be sure it’s going to be either resolved or rejected. Problem in your code is, you can’t await at top level, you’ll have to go with .then().
You can simulate your database access with this diy sleep function aka find()

async function getBankDetailsAsync() {
  let bankDetails = await find();
  return bankDetails;
}

async function find() {
  return new Promise(res => {
    setTimeout(() => {
      res("Bank Details")
    }, 1000)
  })
}

let id = "345";
let bankDetailsForId = getBankDetailsAsync();
console.log(bankDetailsForId);

getBankDetailsAsync()
  .then(deets => {
    bankDetailsForId = deets;
    console.log(bankDetailsForId)
  })

Without the .then() it logs “pending”. You always have to await your Promises somehow.

Concerning the second part, you can chain your database fetches up with lots of .then()s or, if they don’t necessarily depend on each other, fetch them all simultaneously with

Promise.all([find(), find(), find()])
  .then(deetsArray => {
  console.log(deetsArray)
})

If you want to await multiple database ops simultaneously in your getBankDetailsAsync() function, it would look something like this

async function getBankDetailsAsync() {
  let bankDetailsArray = await Promise.all([find(), find(), find()])
  return bankDetailsArray;
}

await and then() are essentially the same.

1 Like

Awesome, this was super helpful and confirmed what I had thought before.

One thing that was a bit confusing was when Mosh said that having a function to await an async function would make sure that the result came.

For example, if I had something like this for your getBankDetailsAsync() function:

async function waitForBankDetails() {
    return await getBankDetailsAsync();
}
let bankDetails = waitForBankDetails();
console.log(bankDetails);

The console.log statement does not have to wait for the waitForBankDetails() function in order to continue, so this would still return pending, right? Did I misunderstand the purpose of the second async function?

Also, I have been wondering, is there a deadline by which an asynchronous call has to finish to finish by? Is it by the end of the program? If so, I think it could be interesting to think of an asynchronously running program as a pizza shop, where multiple pizzas can be in the oven at the same time, deliveries don’t have to be given in the order they were requested, and all the pizzas have to be delivered by the time the pizza shop closes!

You need a function decorated with async to be able to await another async function. Otherwise you have to use .then(). If you don’t do any of these measures, you only have a pending promise to work with.

This returns pending, yes, you don’t have to wait for the Promise to resolve, you can just continue, but that usually throws errors. Well, in Python it does, I’m not sure what happens in Node if you just ignore the promise. But since I’m not getting any errors for not awaited promises, I guess it goes out of scope at some point and just gets garbage collected. :woman_shrugging:

That’s basically an event driven program and the whole purpose of asyncs :smiley: . You wait for an event (pizza order) and prepare it, while asynchroneously accepting other orders and preparing them.