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));
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);