Skip to main content
View on YouTube to comment and like!

about 2 years ago Syntax Podcast

JS Promises Fundamentals - Part 1

Wes Bos

Wes Bos Host

Scott Tolinski

Scott Tolinski Host

Topic 0 03:43

Fetch API returns promises for network requests

Wes Bos

often, I'm in that camp. Like, Node. Maybe we don't need a very opinionated way to do this in the language, but with with promises being able to have a single type.

Wes Bos

Being able to have it as a primitive in the language it will have that it'll work just fine. The same thing with rejecting. You don't have to explicitly reject.

Wes Bos

Another example of promises would be a database query or an insert command, pretty much any database ORM that you're using these days.

Scott Tolinski

If you go off and you know, there used to be libraries, and now we have a standardized

Wes Bos

Yes. And the promises being a feature of the language has been queuing, flow control, The other one being that sometimes you want

Scott Tolinski

If you go off to grab some data from anywhere, and you're most likely using fetch. And if you've ever tried to access that data immediately,

Scott Tolinski

And then and you say, alright. Let me You just return the promise from that function,

Scott Tolinski

then you can, you know, bring that data back, and now we can do something with it. So you've gone off to a trip to the store. You've now come back with the goodies that you you ordered.

Wes Bos

And it's not really, like, a new thing, but it's it's a new API that makes working with deferreds a little bit easier. And a lot of people are like, why are they adding all this garbage? Why don't you just go and use this library that already did it really well? And create user. Whereas the create user function would return a promise, putting in a weight in front of it will will sort of unwrap the promise. It will wait for the promise to resolve and give you the actual data at the end of the day. A weight also is used for generator functions, but we're not getting into that in the promise episode.

Scott Tolinski

fetch API.

Scott Tolinski

wait for that data. Or when when the data does come back or perhaps you failed to get to the store,

Scott Tolinski

you'll know that it returns a promise.

Wes Bos

a promise or or a way to do this type of work. But Mhmm.

Wes Bos

API that does validation Wes you wanna stop your code from running. You wait for something to show up on the page, and then when that thing is on the page, it will resolve. We'll talk about that in just a second, library normally, the the result of a promise is returned immediately.

Wes Bos

means that you can mix and match

Topic 1 16:46

async/await syntax is preferable for readability

Wes Bos

that I've seen is And then, a little wait function is a example of a promise that you might write yourself. So the data that that promise has set out to to go get or to to go and then And You can throw an error, which you might be used to already. You Sanity, you may want to return And if you have to get JSON back, you know it's JSON.

Wes Bos

or you create, like, a a variable that's Node the scope of the dot then and you sort of update it. That's annoying because now you have like an undefined variable for a short amount of time and you have TypeScript. That's a bit tricky.

Wes Bos

I personally do that as well as I await, but I'd use a dot catch to to catch the error in in most cases.

Wes Bos

any, and race,

Scott Tolinski

layer deep. Right?

Wes Bos

canceling promises, aborting promises,

Wes Bos

if you return another promise from that dot then, you can chain them

Wes Bos

which is hard, and it's also really hard to, like, pass data between the 2 of them. So if you

Scott Tolinski

going another where you can use the resolve or reject methods to, like, Wes mentioned moments ago,

Wes Bos

you can continue ongoing. So it's a beautiful API because you can simply just say, like, const user equals await return immediately.

Scott Tolinski

async function. I don't feel like making this function async, so I'll just throw a dot then on there.

Wes Bos

weather data. And then that's really frustrating because where

Wes Bos

for Wes something is resolved, but keep the function going I'll have from a function that will return you data right away, turns into a function that will return a promise Yeah. That's, that's something we have coming up in the next one, which is error handling strategies of, like, mix and matching.

Wes Bos

stream and from running.

Wes Bos

The fetch has, like, a double promise thing, which we'll explain in the in the next episode. Sometimes I'll just chain a little dot then on top of it.

Wes Bos

onto one another.

Scott Tolinski

await just because it reads more like how I would expect it to work, and then I can access the values where I want to access them. Alright. Wait for the value. It's there. Now I can do something with it. But, you know, there certainly are times where I am using a a catch or a dot then as well. I do use a dot catch Sick.

Wes Bos

yeah, I like I like the the strategies. How do you how do you specifically And then the next line below that, you wanna set up, like, an event handler

Wes Bos

once the promise resolves itself,

Scott Tolinski

to your promise of future episodes. Promise it will be good. Peace. I can't When you go off to do a fetch, it it doesn't know how long that's going to take. It says, I'm gonna go get some data. I'll be right back.

Wes Bos

the async await API simply because it reads a lot nicer.

Wes Bos

a dot then, and that will return to you the promise itself, but also the reject

Wes Bos

to listen And if you have a async functions is that inside of an async function, you can simply just return a value.

Scott Tolinski

it is funny because it sometimes it feels haphazard in which I I'll be like, oh, I'm not inside of an

Wes Bos

wait.

Wes Bos

you find yourself having to modify and all of those things need to happen inside of your promise. They can also often chain them together. And then when you're successfully done, you resolve it. If there's an error anywhere along the way, you can reject that promise and say, this is this is explicitly what has happened.

Wes Bos

and put a single dot catch at the end of it, any errors that happen along the chain. Where that becomes an issue is then you have your a weird scope, as well as 5 different ways to handle

Scott Tolinski

variable and pass it and worry about the default values before and after the the promise return. So almost always, I'm using

Wes Bos

you want to go off and fetch something.

Scott Tolinski

I to me, it depends on, like, what I have to do with that data. The thing that's always bugged me about the then methods

Wes Bos

some of the promise helpers, which is all all settled, finally, It was very hard to say, alright. Well, I'm gonna work with this database adapter, while you're waiting for it. So a very common use case

Scott Tolinski

I look forward Yeah. My default is Yes. And I don't think this necessarily fits ESLint there, but there's also

Scott Tolinski

is that you're now I think this is a great idea, though, because, you know, I remember when I first learned about promises black back when they weren't in the browser, you had to use q or Bluebird or one of those. Right? Yeah. I remember being very confused about

Wes Bos

now if you wanna comment Node of them out, then you have to change the signatures again,

Topic 2 15:07

.then, .catch, .finally wait on promises

Scott Tolinski

a third one that a lot of people don't use, which is finally,

Scott Tolinski

If the promise rejects, you would then need to also chain a dot

Scott Tolinski

then you say you have a function call, right, obviously, and then you chain a Scott then to the end of that.

Scott Tolinski

and then that callback

Scott Tolinski

catch.

Wes Bos

and you need to turn the loading state off in both cases. Right? And after a successful return or, We'll talk a little bit more about error handling and and how to mix and match them. There are use cases where you still want to use the dot then. Chaining is is a really nice one instead of just doing await await await. Some people like to chain then then then

Scott Tolinski

which this will go no matter what. So if you find yourself duplicating some logic, maybe, like, you're waiting for a value and then you're setting a state toggle based on that value, if that state toggle is toggled Deno matter what, if there's an error or a fit a success state, you could put that in your finally. So the finally is gonna run no matter what after the catch and after the then.

Scott Tolinski

has the data that's available to you if that promise is resolved correctly.

Scott Tolinski

Dot then has a callback,

Scott Tolinski

You then need to chain a a dot catch in which the error will be available in the callback function. And then there's also,

Scott Tolinski

Alright. Well, let's talk about waiting on those promises. Right? So the main way that a lot of people have done it is with a dot then method.

Wes Bos

on error, I wanna turn the loading state off.

Topic 3 03:00

Promises represent data that will be available later

Wes Bos

a promise from the user.

Wes Bos

I will I have tweeted screenshots of code that I've written, and I'll just, like, mark a function as a sync, and then I'll, like, I'll refactor it to return a promise.

Wes Bos

I'm gonna fail, which is is called rejecting.

Wes Bos

And I thought, like, let's just kick it off with just some common examples of what a promise would be. I know most people listening sort of understand what a promise would be, but let's let's talk about So database queries, every ORM that you work with will return to a promise, and then you can sort of just wait for that to for when somebody clicks something or when a specific event happens. If you were to await that fetch request, the event handler would never run until because you're essentially pausing the use case. Same thing with streams as well. That's pretty common use case Wes, all right, I'm going to set up this

Scott Tolinski

anything. The most common one being you wanna take this 1? Yeah. And I think the one that most people have used is fetch calls.

Wes Bos

any type of data that can be returned from a promise, which is indefinitely There's a new method, which I'll talk a bit more about in a future episode, this idea of deferreds.

Wes Bos

give you some piece of data or

Topic 4 10:08

You can create promises manually or with async functions

Scott Tolinski

Yep. And here's a a small little thing for people who find themselves doing this.

Wes Bos

having a function marked as a sync if you are returning a promise.

Wes Bos

throw a new error. User email has already been registered.

Wes Bos

in front of it. Immediately,

Scott Tolinski

like I mentioned, we're then gonna get into, like, the waiting on a promise bit of this because, again I got sorry. I got one more thing to say about that.

Wes Bos

when you want to bundle together a bunch of functionality. And often you'll have, like, nested promises. So you might have a a promise called create user. Right? And in that create user promise So Welcome to Syntax. Today, we've got a first of 3 shows on promise deep dive. So I was driving home from,

Wes Bos

So if you were to have an async function that returns a promise itself, you're not gonna get into any weird, like, nested

Scott Tolinski

returns a promise,

Wes Bos

And then the 3rd way we have for creating a promise, and this is quite honestly

Wes Bos

at a top level. And this can be handy if you want to method. You simply just return. And because the the function has been marked as a sync, And even if it did, that's something called a synchronous request or a blocking request. And what that would do is it would actually lock up the rest of your application from running. So if you your promises.

Scott Tolinski

Alright. Well, let's talk about waiting on a promise then because like we mentioned, a promise is you know? Yeah. It's a commitment to come back and and you know? I'm promising to to go to the store and get some candy cigarettes. When I come back, I better have those candy cigarettes. Do you remember those, by the way? Did you ever get those in Canada? Yeah. It's it's pretty wild that we just, like, had even on await instead of doing a try catch, though.

Wes Bos

And instead of creating a new promise and putting all of your code inside of a promise callback, which does have use cases, you simply just future functions so that they'll accept the incoming So So, again, a promise is a stop deal with errors Word. But I think that's that's all we have for the 1st episode. Again, that was pretty high level of explaining promises. In the next episode, we're gonna get into

Wes Bos

items that are related to that user, setting a bunch of permissions, Yeah. That's that's really handy if you, like, have, like, a loading state

Scott Tolinski

what you don't wanna do is you don't wanna mark the function as async and then await that promise and then return the result.

Wes Bos

You can have other promises inside of there. And if you return either a value or a promise,

Wes Bos

the actual user once I'm done. But inside of that, you may be doing several things. Right? You may be doing some sort of validation. You might be checking if they have have 1 promise that fetches the weather and then another promise that saves the weather to the database,

Wes Bos

or a function that returns a promise, I I promise I will go and create the user and return to you, Those are reject cases.

Scott Tolinski

If your function I don't know why. I I Wes I don't know why I said that, you know, apprehensively.

Wes Bos

At least I don't know of of any, like, performance downside to, your Node that will return data at some point. And the kind of the cool thing about

Scott Tolinski

and you're returning a promise from the function rather than having to create a new promise and and do it that way. So Word.

Wes Bos

the actual promise itself from that function. There's no harm in, like, sort of double wrapping The chaining the dot thens onto each other, and I should say the way that this works is if you have

Wes Bos

you don't have to use the resolve you can sort of pause that function

Wes Bos

create a function. You mark it with the keyword async agreement that some data will be returned to you. It's a commitment. Like, a promise. Commitment. Yeah.

Wes Bos

and resolve but you could if you if you did have a blocking Something happened inside of this promise where there was an error that happened because of a different library.

Wes Bos

a sink on there, which is why I like the ESLint rule that will be like, you didn't await anything inside of this. What are you doing marking it as a sync? But I don't think there is.

Scott Tolinski

cigarettes, and they're, like, red on the tips. Like, clearly, you're trying to make these fake cigarettes. But I said you're supposed to, like, keep keep them in your mouth. I just chomped them up. That's what I did. They're, like, chomping. I can't. Yeah. I can't do that.

Scott Tolinski

thens that that will be an issue for you. Do you think there is any sort of performance implications there? I I don't know if there is. I'm just wondering. I don't I don't think so. Often,

Wes Bos

sometimes there's an unnecessary I Yes. Yes. Good. Oh, yeah. Let's see. How many promise jokes can we make in these next 3 weeks? And if you want to see all of the errors in your application, Previously, it was like Scott said, you have to use Bluebird or a sync or callbacks.

Topic 5 08:21

Promises can resolve with data or reject on failure

Scott Tolinski

either resolve and complete the promise or reject and fail the promise. Yeah. You are often creating your own promises So instead of using a sync await or anything like that, you have your promise,

Scott Tolinski

Wes we're working on promises.

Scott Tolinski

We'll talk about this in a bit, but that those connect directly to the then. Right? The then method is called once a promise has been resolved. The catch method

Scott Tolinski

using new promise. And you can create a promise, and that gives you a callback

Wes Bos

a negative outcome of a promise is called a reject. And often, you will call reject in your promises the most common way these days, is you mark a function, like, I know most languages have sort of the idea of

Scott Tolinski

so you resolve or reject a promise, and and those things connect very firmly to

Wes Bos

fetch for you or to you would resolve after somebody clicks a button. That's a successful outcome of a promise is called a resolve, the await whatever.

Wes Bos

successfully Resolving a promise is The user did not actually give me access to their webcam.

Scott Tolinski

gets called when something is rejected,

Topic 6 06:03

Database queries return promises

Wes Bos

circumstance,

Wes Bos

where you create a blocking pass the resolver and reject methods to other parts of your application rather than doing your work inside of the promise itself.

Wes Bos

successfully give you the message. Say, I save the data or resolves to the query of the data that's been returned to you. Yep. If you if you notice a pattern here where, basically, testing library at some point in the future, that surround and I'm going to be working with this

Scott Tolinski

we use a a promise. So that way, it takes something that could be blocking and makes it so it does not block the execution of other things, which is one of the reasons why we have to do the whole the whole then thing with promises that we'll get into.

Scott Tolinski

Another thing could be,

Scott Tolinski

anytime something could be blocking, If you wanna access that data outside of the promise, you have to create a

Wes Bos

If your database is not gonna solve You sometimes do have a sync functions that return promises, and and the use case for that is sometimes you want to first await something inside of that,

Topic 7 00:00

Transcript

Scott Tolinski

you'll want to check out Sanity at sentry.ioforward/

Wes Bos

on deep dive into promises. So today, we've got sort of an introduction, understanding in a nice way for your application with promises? pretty common way to do it, and then we also have the ability to await promises. So when you're in a function that is marked as a sync, how promises work, and awaiting them in different ways to create and listen for a promise resolve. Then, 2nd day, we're gonna have 1 on canceling promises, helper methods, and error handling

Wes Bos

dropping off my kids at school today, and I thought, like, an amazing what what should we what should we do? You know? And I have been keeping notes on just, like, all of these things The the finally is super handy for that. And, quite honestly, I don't see it used all that often. So I think I should maybe start using a little bit more myself.

Wes Bos

And then the last 1 we have is returning database right, you could run into the situation where your server's handling incoming requests or or does a bunch of queuing. And getting those to work together was always kind of frustrating. And now that we have we've had them in the the browser for for many, many years, it's much easier.

Wes Bos

working with promises in JavaScript. And I realized, like, man, there's actually quite a bit to that function changes the dot then is a anything that returns a promise, and you can work with them together. This is one thing when there's a new thing called deferreds that have been added to promises.

Scott Tolinski

syntax. Again, we've been using this tool for a long time, and it totally rules. Alright.

Wes Bos

getting into concurrency,

Wes Bos

fetch, canceling them, and deferreds,

Wes Bos

which is a new API in in the browser. So

Scott Tolinski

syntax. You can sign up today and get 2 months for free. Sentry is just a really incredible tool for not only tracking your performance, making sure your application has no bugs, but even just seeing what goes wrong when something goes wrong because things go wrong all the time when we're coding. And you don't want a production application out there that, well, you have no visibility into in case something is blowing up, and you might not even know it. So head on to reduce entry.ioforward/

Scott Tolinski

you are going to enjoy it. I promise you. I was about to make that same joke.

Topic 8 07:20

Browser permissions like webcam access use promises

Wes Bos

running, when you something goes awry. Right? That that database item didn't save correctly.

Wes Bos

and you can continue on with your with your life. So promises have 2 ideas here is that when you when you create a promise, I think await much better. The only time like I'll mix and match them is often with the fetch.

Wes Bos

from that eventually, you get the option to resolve that promise or reject that promise.

Scott Tolinski

requesting the user's permissions for things, like co webcam. Right? The reason why these have to be returned as promises because you're, again, you're waiting for something to come back from the user's computer, whether that is prompting them to do the permissions acceptance or whatever.

Wes Bos

you Mhmm. But Promise Scott with resolvers is another way to create a promise, methods,

Wes Bos

wanna

Topic 9 02:06

Promises help handle asynchronous actions like network requests

Scott Tolinski

with the first

Scott Tolinski

What's the deal with promises? So I think this will be a really great episode. And in this episode, and specifically and then finally gets called no matter what. We'll then we'll talk about those more in a second. So, next step is creating promises. So how do you create your own promise? Oftentimes, we're consuming promises. Right? We're using a a dot then. We're using a async await. We're we're not necessarily writing them, but you can write your own promises

Scott Tolinski

why they're a big Deno, what makes them interesting, how is it different than something like a callback function,

Wes Bos

You get something right away, but a promise is sort of an IOU, it's very hard to actually write code these days I'm gonna resolve once it's actually finished. So what what do you use, Scott, in in most cases? Do you default to sync await? insert that takes 2 seconds, then all of a sudden you're blocking any requests that are coming in for 2 seconds, and that's that's sort of a bad day.

Scott Tolinski

question.

Wes Bos

completion of some data, and that's different than a regular error handling strategies.

Scott Tolinski

yeah. We're getting into promises 101, creating and waiting on promises. So I think we can start this off

Wes Bos

What is a promise, Wes? A promise in JavaScript is an object that represents the eventual So I in most cases, I would say most people use buckle up for the next 3 weeks. We got all kinds of I promise working with promises and architecting him in flow control and all that. So this is going to be the next 3 Mondays are going to be all hasty treats and

Wes Bos

variable or a function return in JavaScript because, a sync.

Share

Empowering developers for over 286197066632 milliseconds!