For example, the Fetch API provides an interface for making network requests, returning
Promises for us to resolve. To use it to get the current weather in Long Beach, we chain together two
In the first, we create a callback function to receive the
Response object and return back its
JSON data. In the second, we create a callback that receives that data and then logs it to the console.
Using Async/Await, the same code becomes:
By wrapping the logic inside an
async function, we can replace the
then callbacks with
await statements. The effect, the code pauses execution on those lines until the Promises resolve! Asynchronous programming becomes synchronous! 😲
Believe it or not, Async/Await is just syntactic sugar. In this article, we will examine how it all works under the hood. To do that, we will attempt to recreate the async function from scratch!
The key insight is to use Generators. Ultimately, we want to create an async function that takes in a generator. That way, we can nest yield statements that look like this:
Doesn’t this look uncannily like the await statements in
getWeather()? In fact, await statements are just yield statements under the hood!
Thus, we need our
async “polyfill” to instantiate the
generator, recursively checking the value of
next until the
Promise resolves. When
done is true, we can finally return the value of the
Promise back to the calling yield statement.
Clever, right? 😉
Example in live code:
Async/Await enables us to write asynchronous code in a synchronous fashion, which produces cleaner and easier-to-understand logic. Under the hood, it’s just syntactic sugar using generators and yield statements to “pause” execution. In other words, async functions can “pull out” the value of a Promise even though it’s nested inside a callback function, giving us the ability to assign it to a variable! We hope this article gave you a better intuition behind this awesome feature coming to ES8! 😇
Russian translation by Alexey Vechkanov:
Reference: Async/Await Specification