0

When using async/await syntax we write it like so:

async function getAllRecords() {
   let records = await getDataFromServer();
   // Do something with records
}

In other words, if you want to await within a function, you need to make sure you use the async keyword as well (as that changes how this code is handled behind the scenes). All good so far.

My question is: are there cases where you define a function using the async keyword, without also using await within the body of the function?

For instance, I came across this:

async sybaseUpdateCustomer(exId, customer, cardType, lastFour, expireMonth, expireYear, billingStreet, billingZip, defaultPaymentMethod) {
    return new Promise((resolve, reject) => {
      console.log(`Updating customer for customer ${customerId} in sybase.`);
      sybase.query(
        "INSERT INTO cc_customers (ex_id, identifier, card_type, last_four, expiration_month, expiration_year, address, zip, isDefault) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
        [exId, customerId, cardType, lastFour, expireMonth, expireYear, billingStreet, billingZip, defaultPaymentMethod],
        (res) => {
          if (res.status == 'failure') return reject(res.data);
          return resolve(true);
        }
      );
    });
}

Notice the async keyword is being used, but there is no await anywhere in the body of the function. Is this correct syntax? And, if so, what is async doing here, and is it necessary for the function to execute correctly?

Muirik
  • 6,049
  • 7
  • 58
  • 116
  • The `async` keyword means the function will always return a `Promise` (see https://stackoverflow.com/q/35302431/4636715). So, regarding your sample function body returns a Promise, it is perfectly valid. – vahdet Sep 16 '19 at 13:45
  • if you notice, what is happening in the 2nd example is that the function returns a Promise, which it itself an async object. So yes it makes sense not to await here. What is returned to the caller is another asynchronous context. – ADyson Sep 16 '19 at 13:45
  • @ADyson, I did notice that, yes, but then I think to myself, if you're explicitly setting up the promise within the function, anyway, why use the "async" keyword at all? For the sake of code readability, maybe? It does allow other developers to quickly notice this is going to involve a promise, but one could also argue it's functionally redundant. – Muirik Sep 16 '19 at 14:28

2 Answers2

4

An async function returns a Promise, and it's fine to use the value returned by an async function directly as a Promise without using the await keyword.

The async might or might not be necessary on the function being called, depending on how it's written. async is definitely required if the function has any awaits inside of it, and it's also necessary if the function returns a value, say a number, which is meant to be treated as Promise<number>.

kshetline
  • 12,547
  • 4
  • 37
  • 73
1

async means two things: one, it's necessary to await things in the function's body, and two, the return value will be wrapped in a promise. Even if there's no return statement, the result will be undefined wrapped with a promise. Here:

const foo = async () => {};
foo().then(console.log);

So I guess async without any await is another way of doing Promise.resolve().

mbojko
  • 13,503
  • 1
  • 16
  • 26
  • To me it seems redundant in the example I included above, because `async` sets things up for a promise, but then in the code above the promise is then explicitly set up in the function body, anyway. – Muirik Sep 16 '19 at 14:24
  • Yes, it is kind of redundant. – mbojko Sep 16 '19 at 15:31