Skip to content
โ† back to home

The Async Await Episode I Promised

Fireship

youtubeยท 11:55standard

1.Introduction to Asynchronous JavaScript

0:00 / 0:43

This chapter introduces the concept of asynchronous programming in JavaScript, highlighting its importance due to JavaScript's single-threaded nature. It outlines the topics to be covered, including the event loop, callbacks, promises, and async/await.

  • JavaScript
  • Asynchronous Programming

What's inside this course

  1. 0:00

    1. Introduction to Asynchronous JavaScript

    This chapter introduces the concept of asynchronous programming in JavaScript, highlighting its importance due to JavaScript's single-threaded nature. It outlines the topics to be covered, including the event loop, callbacks, promises, and async/await.

  2. 0:43

    2. Understanding the JavaScript Event Loop

    This chapter provides an overview of the event loop in browsers and Node.js. It explains how synchronous code runs first, while asynchronous events are queued up to be called back later, distinguishing between macro tasks and micro tasks.

  3. 1:48

    3. Event Loop: Macro vs. Micro Task Priority

    This chapter demonstrates the priority difference between macro tasks and micro tasks using a code example. It shows that even if a `setTimeout` (macro task) is queued before a promise (micro task), the promise will execute first due to its higher priority.

  4. 4:03

    4. Consuming Promises and Error Handling

    This chapter explains how to consume promise-based APIs like `fetch` and chain multiple promises together using `.then()`. It also covers how to handle errors in a promise chain using a single `.catch()` function, which is a significant improvement over callback-based error handling.

  5. 5:50

    5. Creating Promises and Avoiding Blocking Code

    This chapter delves into creating custom promises and highlights a common pitfall: wrapping synchronous blocking code directly in a promise. It demonstrates how to correctly refactor code to ensure synchronous operations run quickly by placing blocking code inside a resolved promise's callback, thus executing it as a micro task.

  6. 8:57

    6. Async Functions and the Await Keyword

    This chapter introduces `async` and `await` as syntactic sugar for promises, making asynchronous code read like synchronous code. It explains that an `async` function always returns a promise and sets up a context for using `await` to pause function execution until a promise resolves, simplifying the handling of multiple asynchronous operations.

  7. 11:25

    7. Concurrent Execution with Promise.all

    This chapter addresses a common mistake with `async/await`: failing to run code concurrently. It demonstrates how to use `Promise.all` to execute multiple independent promises simultaneously, significantly improving performance by avoiding unnecessary sequential waiting, especially for network requests.

Every chapter ends with a checkpoint (quiz, flashcards, retell, diagram, or prediction) and the course closes with a final boss-fight. More courses โ†’

Transcript (366 segments)
0:00[Music]
0:07javascript is a single-threaded
0:08programming language yet everything we
0:10do on the web tends to be blocking or
0:12time-consuming which means that
0:14asynchronous programming is an essential
0:15skill for any JavaScript developer
0:17today's video will focus primarily on
0:19the amazing syntactic sugar provided by
0:22async await but before we can get there
0:24we really need to understand things from
0:25the ground up starting with the browser
0:27or nodejs event loop callbacks promises
0:30and then finally async await and we're
0:32going to do this without making a single
0:34joke about a sink or a wave if you're
0:36new here like and subscribe and we'll be
0:37giving away another one of a kind
0:39t-shirt with this video all you have to
0:40do is leave a comment below and we'll
0:42pick a random winner next week in order
0:44to understand anything async you really
0:46need to first understand the event loop
0:48this is ace I hope that clears up any
0:50questions you have I'm going to give you
0:53the general overview but I highly
0:54recommend you watch this talk from Jake
0:56Archibald which is the best explanation
0:58of the event loop that I've ever seen
0:59then after you're done watching that
1:01talk you should check out Stephen
1:02fluence demos with angular Channel which
1:04just released a video about callbacks
1:06which are one of the things that happen
1:07within the event loop so what is the
1:09event loop and what does it have to do
1:11with async away both the browser and
1:13nodejs are always running a single
1:15threaded event loop to run your code on
1:17the first go around it will run all of
1:19your synchronous code but it might also
1:21queue up asynchronous events to be
1:23called back later you say here's a
1:24function that I need to run but first I
1:26need to go get some data from the
1:27network the event loop says okay I'll
1:29keep doing my thing while you do your
1:31thing in a separate thread pool then at
1:33some point in the future get data will
1:35finish and let the event loop know that
1:36it's ready to be called back now this is
1:38where things get interesting if it's a
1:40macro task like a set timeout or set
1:42interval it will be executed on the next
1:45event loop but if it's a micro task like
1:47a fulfilled promise then it will be
1:49called back before the start of the next
1:50event loop let's look at the
1:52implications of this by writing some
1:53actual code first we will write a
1:55console log which is synchronous then
1:57we'll throw in a set timeout but give it
1:59a time delay of zero milliseconds then
2:01we'll have a promise that resolves right
2:03away and lastly we will add another
2:05console log for one more synchronous
2:07line of code so nothing here has any
2:10actual time delay so intuitively I would
2:12think that
2:12each line of code would be executed one
2:14by one but that's not how things work in
2:16the event loop if we execute this code
2:19you can see that first line gets logged
2:20up right away because it's running on
2:22the main thread then if we run the
2:23second line it's being queued for a
2:25future task then the promise is being
2:28cued to run in the micro task queue
2:30immediately after this current task and
2:32finally the last console log gets
2:34executed right away so even though the
2:36set timeout call back was queued up
2:38before the promise the promise still
2:40gets executed first because of the
2:41priority of the micro task queue so now
2:44that you know how the event loop works
2:45we can start looking at promises first
2:48I'll show you how a promise based API
2:49might be consumed and then we'll look at
2:51how we actually create our own promises
2:52from scratch so fetch is a browser-based
2:55API but it's also available on node via
2:57the node fetch library and it allows us
2:59to hit an HTTP endpoint and have the
3:02response returned to us as a promise of
3:04the response fetching data from a remote
3:06server is always going to be a sync so
3:08we can queue up the promise then provide
3:10it with a callback to map it to JSON the
3:13great thing about promises is that we
3:14can chain them together mapping to JSON
3:17is also a promise so we can return that
3:19promise from the original then callback
3:21and then in the next one we'll have the
3:23actual user data as a plain JavaScript
3:25object if we go ahead and run this code
3:28you'll see it runs our console log first
3:30and then it retrieves the data from the
3:31API and console logs that afterwards the
3:35great thing about promises is that you
3:36can catch all errors in the chain with a
3:38single function we can do this by adding
3:41catch to the bottom of our promise chain
3:43and it will handle errors that happen
3:45anywhere within our asynchronous code if
3:47this code were callback based we'd have
3:48to have a separate error handler for
3:50every single one of the asynchronous
3:52operations so if an error is thrown
3:54anywhere in our code it's going to
3:56bypass all of the future then callbacks
3:58and go straight to the catch callback
4:00when you start creating promises that's
4:03when you're more likely to screw things
4:04up first I'm setting up a log function
4:07so I can show you the elapsed time
4:09between each line of code up a while
4:11loop that loops a billion times
4:12arbitrarily if we run this on the main
4:15thread it's going to block all of their
4:17code from executing until the billion
4:19loops are done so we'll do one console
4:21log run our while loop and then do
4:23another console log after that and you
4:25can see it takes about seven
4:26milliseconds to finish the while loop
4:28our script is essentially frozen until
4:30that while loop is complete so let's go
4:32ahead and wrap this code in a promise so
4:34we can get it off the main thread and
4:35execute it as a micro task this is one
4:38tricky little way you might screw things
4:39up so we create a new promise we add our
4:42code inside that promise and then we
4:44have it resolved to that value when done
4:46so you might think that because we're
4:48wrapping this in a promise that we're
4:49going to execute this off the main
4:51thread but the actual creation of the
4:53promise and that big while loop is still
4:55happening on the main thread it's only
4:57the resolving of the value that happens
4:59as a micro task
5:01so the first synchronous line gets
5:02logged right away and the second one
5:04should too but there's still a 700
5:06millisecond delay because that while
5:08loop is still blocking on the main
5:09thread so to ensure that all of our
5:12synchronous code runs as fast as
5:13possible we'll refactor our code once
5:15again to say promise resolve then we'll
5:18run the while loop inside of that result
5:20promises callback by putting this code
5:22inside of a resolved promise we can be
5:24guaranteed that it will be executed
5:26after all the synchronous code in the
5:27current macro task has completed if we
5:30go ahead and run our script again you
5:32can see we get our two console logs
5:33right away and then finally the promise
5:35resolves after 700 milliseconds so now
5:38that you know all that stuff you should
5:39be in the clear to use async await
5:41responsibly we already know that
5:43promises are a huge improvement over
5:44callbacks but promises can still be
5:47really hard to read and follow
5:48especially when you have a long chain of
5:50multiple asynchronous events async await
5:53really just boils down to syntactic
5:55sugar to make your asynchronous code
5:56read like synchronous code first let's
5:59look at the async part of the equation
6:01and see what that does so here we have a
6:03regular function that does nothing and
6:05if we put the async keyword in front of
6:07it we have a function that returns a
6:09promise of nothing so whatever gets
6:12returned inside this function will be a
6:13promise of that value I'm going to reuse
6:17this get fruit function throughout the
6:18lesson just to simulate what a promise
6:20based API looks like in this case the
6:22user can pass in the name of a fruit and
6:24then the function will resolve to the
6:26value of the fruit emoji from this
6:28object and just to make this a little
6:30more clear if we didn't use the async
6:32keyword we could write this function by
6:34just returning a promise that resolves
6:37to this value so when you use the async
6:39keyword the matte
6:40that happens is that it takes the return
6:42value and automatically resolves it as a
6:44promise but that's not everything that
6:46it does it also sets up a context for
6:49you to use the await keyword the real
6:52power of an async function comes when
6:54you combine it with the away keyword to
6:55pause the execution of the function now
6:58I'm going to write a second async
7:00function called make smoothie what we
7:02need to do is get multiple fruits and
7:04then combine them together as a single
7:06value instead of chaining together a
7:08bunch of then callbacks we can just have
7:10a promise resolve to the value of a
7:12variable a weight is like saying pause
7:14the execution of this function until the
7:16get fruit promise results to a value at
7:18which point we can use it as the
7:20variable a and then we'll move on to the
7:22next line of code after we get a
7:24pineapple we can then get a strawberry
7:26and then we'll turn them together as an
7:28array one of the most annoying things
7:30with promises is that it's kind of
7:32difficult to share result values between
7:34multiple steps in the promise chain but
7:36async/await solves this problem really
7:38nicely the code on the right is what
7:41this would look like if we wrote it with
7:42just regular promises and as you can see
7:44there's a lot more code and a lot more
7:45complexity there now if you're already a
7:48JavaScript expert then I'm kind of
7:49trolling you because you know that the
7:51code on the left is making the single
7:52biggest mistake that people make when
7:54using async await and that is failing to
7:56run the code concurrently if we go back
7:59to the code on the left you can see that
8:00we're waiting for a pineapple to resolve
8:02and then we're getting a strawberry
8:04afterwards but we could get both of
8:06these things at the same time you really
8:08only need to await one thing after the
8:10other if the second value is dependent
8:12on the first value for example if you
8:13need to get a user ID before you can
8:15then retrieve some data from the
8:17database let's imagine we're making
8:19these calls from a remote API and
8:21there's about a second of latency if we
8:23run this code again with a delay you can
8:24see it takes a full second to get the
8:26first fruit and then a full second to
8:27get the second fruit but the whole point
8:29of the event loop is to avoid blocking
8:31code like this so we know that an async
8:34function always returns a promise so
8:35instead of doing one after the other we
8:38can add both of our promises to promise
8:40all this will tell all the promises in
8:42the array to run concurrently and then
8:45have the resolved values be at that
8:46index in the array so this is something
8:48that you should always be thinking about
8:50when working with async functions you
8:52don't want to accidentally pause
8:53function unnecessarily so instead of
8:56awaiting a whole bunch of individual
8:57promises you might want to add all your
8:59promises to an array and then await that
9:01promise all call and as you can see here
9:04we've doubled the speed of the original
9:06function another nice benefit of async
9:08await is error handling instead of
9:11chaining a catch callback to our promise
9:12chain we can just wrap our code in a
9:14try-catch block this offers much better
9:16flexibility when handling errors that
9:18might occur across multiple promises if
9:20we take our code from the last example
9:22and throw an error in the middle of it
9:24we can then catch that error down here
9:26in the catch block the first thing we'll
9:28probably want to do here is console.log
9:29the error and then we can either catch
9:31the error and throw another error or we
9:34can catch the error and return a value
9:35your decision here will dictate the
9:38control flow for the consumer of this
9:40promise if you return a value it's
9:42basically like ignoring the error and
9:43then providing some replacement value so
9:46the consumer the promise won't get an
9:47error but instead they'll get the result
9:49value inside of the then callback in
9:51contrast if we throw an error inside of
9:53our catch block it will break the
9:54consumers promise chain and be handled
9:56by their catch callback now I want to
9:59show you a couple of tricks to make your
10:00code as sweet as possible let's imagine
10:02we have a string of IDs and then we want
10:04to retrieve all these ideas from the
10:06database we can use a ray map to convert
10:08them to an array of promises and then
10:10resolve them all concurrently using
10:12promise doll that looks great but you
10:14need to be careful when using
10:15async/await
10:16in a map or for each loop because it
10:19won't actually pause the function in
10:21this context so normally we would expect
10:22this loop to stop if we do a wait get
10:25fruit but that's actually not what
10:26happens in this case instead it will run
10:28all these promises concurrently so that
10:30might not be the behavior that you're
10:32expecting if you want to run a loop and
10:34have every iteration in that loop a way
10:36to promise you need to use a traditional
10:38for loop so you can write async
10:40functions and then write a for loop
10:42inside that function and then use the
10:44await keyword inside the loop when you
10:47write your code like this it will pause
10:48each step of a loop until that promise
10:50is resolved but more often than not
10:52you'll probably want to run everything
10:54concurrently and a cool thing you can do
10:56is use the await keyword directly in a
10:58for loop if you have a promise that you
11:00know results to an array you can
11:02actually just use the await keyword
11:03directly in your loop so you can say for
11:05await in your code what
11:07we'll await the array of items to
11:09resolve and then loop over them
11:10immediately after and as you can
11:13probably imagine you can also use the
11:14await keyword in your conditionals on
11:17the left side of the conditional we can
11:19await the result value from a promise
11:21and then we can see if it's equal to
11:22some other value so that gives you a
11:25super concise way to write conditional
11:27expressions when working with promises
11:29hopefully that gives you some ideas on
11:31what you can do with async await in ES 7
11:33or typescript it is truly one of the
11:36sweetest things to ever happen to
11:37JavaScript if this video helped you
11:39please like and subscribe and make sure
11:41to join the live stream next week for
11:42the t-shirt giveaway and if you want to
11:44take your development to the next level
11:45consider becoming a pro member at
11:47angular firebase comm you'll get access
11:49to all kinds of advanced content
11:51designed to help you build and ship your
11:53app faster thanks for watching and I'll
11:55talk to you soon