The async
keyword is not only about allowing the await
keyword in the function. It ensures that your function will always return a Promise
, even when exceptions are thrown.
Let's define two identical functions which do not use the await
keyword:
async function fnUsingAsync() {
// Synchronously throw half of the time
if (Math.random() < .5)
throw new Error('synchronous error')
// Return fulfilled/rejected promises half of the time
return Math.random() < .5 ?
Promise.resolve('success') :
Promise.reject(new Error('asynchronous error');
}
function fnNotUsingAsync(x) {
// Use the exact same body here than function above
}
When calling them, the result is different in case of failure.
// when using the async keyword, the function always returns a promise
// which can be fulfilled or rejected.
// No need for try-catch!
fnUsingAsync()
.then(result => /* result === 'success' */)
.catch(error => /* catch both synchronous and asynchronous error */);
// Otherwise, you will need to use a try-catch statement, because
// the exception won't be converted to a rejected promise.
try {
fnNotUsingAsync()
.then(result => /* result === 'success' */)
.catch(error => /* catch asynchronous error only */)
}
catch (error) {
/* catch synchronous error only */
}