For a long time, asynchronous, event-driven callbacks were an unavoidable part of JS development.
To solve the issue with callbacks, a new concept, “Promises” were added to JS. Promises allow you to write asynchronous logic while avoiding the nesting issues that previously plagued callback-based code.
What is a Promise?
A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action’s eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.
A Promise is in one of these states:
- ⏳ pending: initial state, neither fulfilled nor rejected.
- ✅ fulfilled: meaning that the operation was completed successfully.
- ❌ rejected: meaning that the operation failed.
The biggest advantage of Promises over callbacks is readability and chain ability.
While Promises are great, they still left something to be desired. At the end of the day, writing Promises still didn’t feel “native”. To remedy this, the ECMAScript committee decided to add a new method of utilizing promises, async, and await:
async and await
The one caveat being, anything you await must have been declared async:
required definition of makeHttpRequest in prev example
It’s also possible to await a Promise directly since an async function is really just a fancy Promise wrapper. This also means the async/await code and the Promise code, are functionally equivalent.