Skip to content

Instantly share code, notes, and snippets.

@deskoh
Last active January 8, 2021 04:34
Show Gist options
  • Save deskoh/077b3f2096f45d34c16dba58dbeda05b to your computer and use it in GitHub Desktop.
Save deskoh/077b3f2096f45d34c16dba58dbeda05b to your computer and use it in GitHub Desktop.
JavaScript Async Function

async function ensures function always returns a promise

Non-promise return value will be wrapped in a promise

async function increment(num) {
  // Value will be wrapped in a promise
  return num + 1;
}

// Logs: 4
increment(3).then(num => console.log(num));

Promise returned will auto-unwrap, i.e. it does not return a promise for a promise for the value

async function increment(num) {
  // it doesn't matter whether you put an `await` here (even though it is uncessary)
  // Promise returned will auto-unwrap
  return Promise.resolve(num + 1);
}

// Logs: 4
increment(3).then(num => console.log(num));

Error thrown will be wrapped in a rejected promise

async function increment(num) {
  // returns a rejected promise, equivalent to returning Promise.reject(new Error(num));
  throw new Error(num);
  // throw num; <- works as well but no stack trace
}

increment(3).catch(e => console.log(e));

⚠️Bad-style.🚨

Non-async function that return promise or throw error require different constructs to handle both cases.

// ⚠️Bad-style.🚨
function increment(num) {
  // Errors are thrown synchronously, i.e. they cannot be caught using .catch
  if (typeof num !== 'number') throw new Error('failed');
  return Promise.resolve(num + 1);
}

// 🚫Following code for error handling is wrong as catch block won't be called.
increment(false)
  .then(result => console.log(result))
  .catch((error) => console.log(error));

// Following works but is bad-style
try {
  increment(false)
    .then(result => console.log(result))
  // Following works as well.
  // console.log(await increment(false));
}
catch (error) {
  console.log('error', error);
}

Marking function as async will allow consistent handling of both resolved and rejected promise.

async function incrementAsync(num) {
  // Errors thrown are wrapped in rejected Promise.
  if (typeof num !== 'number') throw new Error('failed');
  return new Promise.resolve(num + 1);
}

incrementAsync(false)
  .then(result => console.log(result))
  .catch('error', error);

Related linting rule

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment