Episode Transcript
Transcripts are displayed as originally observed. Some content, including advertisements may have changed.
Use Ctrl + F to search
0:00
Ooh, welcome to syntax on this Monday
0:02
hasty treat. We're gonna be hitting you
0:04
with part three of three in
0:06
our series on promises. We're gonna
0:09
be talking about some new stuff,
0:11
like with resolvers. We're gonna be
0:13
talking about, you know, practical stuff
0:15
with fetch. We're gonna be talking
0:17
about flow control, concurrency, throttling, queues,
0:19
all of those types of things.
0:22
Basically, we got the basics. We
0:24
got the intermediate kind of syntax
0:26
stuff. Now, here's what we want.
0:28
We wanna learn how to get even
0:30
deeper with this. And if you're
0:32
getting deeper into any type of new topic
0:35
or code, you're gonna make mistakes, you're gonna
0:37
cause bugs. Potentially, you're going to end up
0:40
with some performance issues as well. And to track
0:42
all of that stuff and make sure that you
0:44
have a handle on it, you're gonna want to
0:46
use Sentry at sentry.io. That's
0:49
s-e-n-t-r-y.io/syntax. Sign
0:51
up and get two months for free. And
0:54
seriously, just give it a rip because
0:56
once you get used to those dashboards
0:59
and once you get used to those dashboards in your
1:02
project and your application, it's really hard to
1:04
live without that visibility and to just kind
1:06
of be flying blind on what your users
1:08
are actually hitting in your site. So let's
1:11
get on into it. I
1:14
have deferred the starting of this episode
1:16
long enough. We're gonna be talking about
1:18
the first thing, deferred
1:20
promises, and talking about with
1:23
resolvers, which is newly available.
1:26
So Wes, do you wanna, I've not
1:28
used with resolvers. I'm super interested
1:30
in what this is and how to use it.
1:33
Yeah, so previously,
1:36
if you wanted to access a promise and
1:41
its resolve and reject methods
1:43
outside of the promise body,
1:47
what you've had to do is you had to create
1:49
a variable outside of the scope of that promise. And
1:51
then when you get inside of it, you have to
1:53
update the variable that's outside. That works
1:55
really well. That whole pattern is called
1:57
a deferred and that's something we've had.
2:00
And Jake Query had deferred for a
2:02
while. Air. It still does. and it's
2:04
It's not a new concept, imprint programming,
2:07
but it's not something we've had in
2:09
Javascript, and there's lots of libraries out
2:11
there that were just made for simply
2:13
making a deferred in Lusaka public with
2:16
why might you want that? I've talked
2:18
about this on the podcast before his.
2:21
If you want to instead of having a
2:24
pass your work into a promise no often
2:26
when you're you're doing a bunch of stuff
2:28
what your the as you make a functions
2:30
your return a new promise and then all
2:32
of the work needs to happen inside of
2:35
that's and sometimes it makes a little bit
2:37
more sense to. Instead. Of
2:39
passing you work into the promise you and a
2:41
pass the. Promise. Itself along
2:43
with it's controls it's resolve and or
2:45
reject methods. You want to return that
2:47
from a function so that you can
2:49
wire and up to buttons. He may
2:51
want to pass it to A success
2:53
Call back of in Other A P
2:55
I am. And promised
2:57
that with resolve as rule will do
3:00
that for you a good it is
3:02
sort of surfaces the result reject methods
3:04
alongside the actual promise where this is
3:06
is really useful is in streams if
3:09
you want to be able to. With
3:12
streams, the way that works is that you
3:14
get a stream. You.
3:16
Listen for was called songs I
3:18
know Scott you're working with the
3:20
get users the web semi yeah
3:22
right now to stream in video
3:25
chunks Is that what? Yes Yes
3:27
yeah and sending them to over
3:29
http to a rest a process
3:31
which is then collecting them all
3:33
in a temp file and then
3:35
once the process is over writing
3:38
that temp file to a video
3:40
file with as as Mpeg. So
3:42
yes Currently doing that. Up
3:44
as really cool kids with in the browser
3:46
with media recorder. The way that it works
3:49
is that you you create a meteor a
3:51
quarter. You listen for
3:53
chunks. Which is basically every
3:55
and are you can say how many seconds. But
3:57
imagine if we have three seconds a video. The
4:00
trunk every three seconds and unaware that it
4:02
works is you. You put those chunks into
4:04
an array and then you wait for. It
4:07
to be finished and then when it's finished
4:09
you take all those shanxi, put them together
4:11
and you get of a video file at
4:13
the other end right? Yeah, I'm that streaming
4:15
eighty I is based on of sense. It's
4:17
like on data rights and. When
4:20
you work was streaming a T I's it's It's
4:22
not a promise as chunks, but if you just
4:24
care. About the output result
4:26
you can use the promise that with
4:29
resolve verse to you can say like
4:31
on error and on cancel of the
4:33
meteor a quarter is equal to reject
4:35
and then on on thinnest you give
4:38
it the resolve method and you can
4:40
get past the the chunks to that
4:42
so. It. It's
4:44
not against nothing we could never do
4:46
before, and it was very easy. For
4:48
is just like one more level of
4:50
indentation inside of a promise. But there's
4:52
one last nested promise. one less weird
4:54
scoping issue that we need with this
4:56
sort. a helper method. Yeah in it.
4:58
It's actually funny. was the you say
5:00
that? Because I've used. A
5:02
Libraries To. Collect. As
5:05
stream before as a promise. they
5:07
collect stream to promise because when
5:10
working with Braintree, every single one
5:12
of their search a P Eyes
5:14
returns a stream rather than. You.
5:17
Can't just oh a think away he pinches a
5:19
we really easy to come in and it's of
5:21
Knox's as hell when you're doing like oh let
5:24
me to do a quick a C P car
5:26
and I don't want to have to return to
5:28
stream back to the you I I want to
5:30
collect Tina him send it to the yeah when
5:32
he added yeah that's actually I've been wanting to
5:34
make this for a while as like some sort
5:37
of like. Custom class that extends
5:39
the promise and it gives you
5:41
both the stream events and u
5:43
ten. Oh wait it yes because.
5:46
Sometimes. I care about both and why
5:48
to output but I also want to listen
5:50
for. The. actual and like achieve
5:52
with you would be good example rights i
5:55
care about the end tax that i get
5:57
from chat t v t but i also
5:59
want display the text as it's being
6:01
streamed in from the server. So
6:04
I kind of want both. So I'm I'm
6:06
sure somebody has already built that wouldn't be
6:08
it wouldn't be too tricky. Let's
6:11
talk about fetch. We know we've talked about
6:13
fetch before fetch. You pass it a URL,
6:15
it returns a promise. The kind of interesting
6:17
thing here is that the first promise of
6:20
a fetch is response
6:22
as soon as the server comes back
6:24
with its headers. So the way that
6:27
a web request works is
6:29
that request something from a server
6:32
and the server is going to come back
6:34
to you immediately with a
6:36
some information. It might not be all of
6:38
the information, but you do get the initial
6:41
headers back and in that you can check
6:43
for the header response code. You
6:46
can return most commonly. We all
6:48
are doing dot
6:50
JSON, right? And people have
6:52
often wondered like why is fetch two
6:55
promises the first one and then you
6:57
immediately from that you return response that
6:59
JSON and then you have access to
7:01
the actual data and that's because that's
7:03
that's the way servers work. You you
7:06
you get the the initial headers
7:08
first and then if you
7:10
want all the whole payload of the body
7:12
of the response, you have sometimes wait a
7:14
little bit longer for all of that to
7:17
to sort of come in. So most
7:19
likely you're checking for a response code. You're
7:21
getting dot text or JSON, but you are
7:24
also we did a whole episode on streams.
7:26
You may be streaming in the result
7:29
or using server sent events from the
7:31
server. Whereas like like chat GBT a
7:33
lot of these things are as
7:36
they are generating the
7:38
actual output. They
7:41
are streaming it to the browser. So I
7:43
used to think like while you're using chat
7:45
GBT. They're just doing this like fake typing
7:47
to make it feel real and the actual
7:49
answer that is that's actually not true. It's
7:52
it's literally coming up with
7:54
the result and firing it out
7:57
the door before even knows that it
7:59
is done. And I
8:01
even I've been sorry go ahead know it
8:03
and it's one of the reasons why chat
8:05
GPT isn't great at commenting code If it's
8:08
also creating the code if you tell
8:10
it to create code and comment the
8:12
code it always puts the comments below
8:15
The code it just wrote because unless
8:18
it's writing the comments first Maybe you could tell it
8:20
to do that it's kind of
8:22
like coming up with what it's trying to
8:24
do as it's doing it Yeah, I don't
8:26
even know when I'm gonna be done. Yeah,
8:28
here's what I've got so far And I've
8:31
noticed on I use
8:33
raycast They just rolled out
8:35
Claude haiku support and I
8:37
notice using the Claude one sometimes
8:39
it's like eight or
8:42
ten words into the response and then
8:44
it just clears it and puts something
8:46
different in and it must be because
8:49
as it's coming up with the result and as it's
8:51
Imagining more of the sentence it goes. You
8:53
know what those first eight words
8:55
I said we're not could be a bit
8:58
better and it replaces it So
9:00
I thought that was kind of interesting with
9:02
streaming Flow control.
9:04
How do you how do you? flow
9:07
through promises First
9:10
of all looping over promises you can use
9:12
a for of loop and you can await
9:15
Inside of a for loop.
9:17
This makes everything synchronous meaning
9:20
or series is often
9:22
a good word for that because the
9:25
word synchronous in in JavaScript
9:27
often means that it's blocking but
9:30
in our case You simply are just like pausing the
9:32
for loop as you're doing it
9:34
And that is a good use case if you want
9:36
to do one thing after another Like
9:38
we talked about me downloading ten thousand
9:40
files a couple episodes ago I initially
9:43
had wrote a for loop and That
9:45
was kind of slow because you download
9:47
one file you wait for it to finish Then
9:50
you do the next one then you do
9:52
the next one in in reality There's some
9:54
probably some sort of use case in
9:57
between doing them in series, which is one after
9:59
another. And. Doing them all
10:01
at once with promised are all settled which
10:03
is ten thousand at once Soon some sort
10:05
of middle ground all. talk about that and
10:07
just a second. Yeah I can think of
10:10
like some A P Ice to they returned
10:12
things in pages see you could say hey
10:14
go off and such page one or eight
10:16
page to his comeback sometimes would they do
10:18
is they give you like that like a
10:20
T for what the page is so the
10:22
you past that into the next batch call
10:24
the new pet like the data that. Precedes.
10:27
It matters for the data that you're trying
10:29
to get neck so that be a good
10:31
reason to do a yes yeah yeah that's
10:33
that's a great use just as sometimes a
10:35
p I will tell you how many pages
10:37
there are and you could fetch them all
10:40
at once. Mum often. Made. Oh
10:42
no, you didn't announce. yeah, I'm going until
10:44
there's no more and often Only way for
10:46
you to tell that is. The.
10:48
Next time you sets one, the result is
10:50
empty. Yeah, they are out. What the southern
10:52
here. I must have reached the end of
10:54
the road and I no longer have to
10:56
to keep doing that. Birds. And
10:58
also and cursors that some you haven't talked about
11:01
a lot as well as. Sometimes.
11:04
Eighty eyes are not based on pages,
11:06
they're based on cursors, meaning that in
11:08
order to get the items after, The.
11:10
Ones you need like a cursor
11:13
idea isn't any you. You. Can't
11:15
do it until you have the cursor from the the
11:17
page before it. You
11:19
can't use. Like a map if
11:21
you have an array of like names and you
11:23
want assessed Michael He of Scots. West. And
11:26
Cj you wanna go to the get have
11:28
a t I set all three of our
11:30
profiles often. What people will do is your
11:32
map over. Each. Of those
11:34
strings and return a promise. Like.
11:37
Return affects request that goes to those
11:39
those three your routes and then you'll
11:41
raft the at in a promise are
11:43
all settled to get all three of
11:45
on those run concurrently meaning they run.
11:47
At. The same time it's not technically we have
11:50
a whole so on that lets. It's. You
11:52
can think of it as that. A
11:54
while loop, again. a while if is not something I
11:56
reach for all the time. Probably. A
11:58
couple times a year, but you can. They await inside
12:01
of a while loop which can
12:03
be useful if you want to
12:05
just. Wait, For than
12:07
the next item to come through. While.
12:10
It yeah don't find myself using
12:12
while it that often but the
12:14
other day when did come up
12:16
and i i while loop dead
12:19
that's for sure. and then ah
12:21
concurrency throttling queuing so. I.
12:23
Find myself getting into this area
12:25
a lot where. I. Need
12:27
to make a whole bunch. It's almost always
12:30
with Fetch you know and is download a
12:32
whole bunch of files. I need to hidden
12:34
a P I a bunch of times to
12:36
get all this data and you find yourself
12:38
in that situation where it is way too
12:40
slow to do them in series one after
12:43
another. But it is. Not.
12:45
Possible to run them all at
12:47
once because. That. Warm like
12:49
your internet provider will probably shut you
12:51
down or you'll hit some sorta like
12:54
de dos thing. If you send ten
12:56
thousand requests to download files to in
12:58
a P Ice, you're probably going to
13:00
get in trouble. So.
13:03
Is are some really nice
13:05
packages out there specifically: p
13:07
Map p Limits since Race
13:09
or Us has. Process
13:12
Team, different P-in the hangs and
13:14
they're all like little utility libraries.
13:16
Classy. I forget which one I
13:19
need every single time and I
13:21
have to read the docs I'm
13:23
but like something like P Map
13:26
will allow you to create an
13:28
array of possible promises. South Loop,
13:30
over. This. List of
13:32
ten thousand and files and return a
13:34
function that will download a file once
13:37
it has been triggered and you give
13:39
all of those to p Map and
13:41
you say. Run
13:43
five at a time at most and when
13:45
it will do that was simply just and
13:47
I'll fire off five and then as as
13:49
at the first one finishes it goes under
13:51
for and asserts the next once as as
13:53
the next on that's that's better than chunking
13:55
biggest chunking will do like five at a
13:57
time way for the all to finish noon.
13:59
Another nother. While lemme lemme seven years
14:01
whereas like concurrent mapping will always
14:03
be running five and always tearing
14:06
off a new one as soon
14:08
as there is a single spot.
14:10
Down some nice. Yeah it's pretty heady. I
14:12
you see is this thing called a sink
14:14
J S. For. Call.
14:17
Back based architecture and but I don't use
14:19
it all the time and I don't use
14:21
any more because. Between. Promises,
14:23
prompts, all settled, and these little
14:26
helper functions I find them to
14:28
be more than enough. There's also.
14:31
Like. P Limit P Throttle P
14:33
D Bounce These will allow you
14:35
to only run the matter after
14:37
a certain amount of time or
14:39
at most every two minutes. So
14:41
often you'll only be allowed to
14:43
create. Sixty. Requests per
14:46
hour so you want to say or
14:48
or six years as per minute So
14:50
like, okay, would don't run more than
14:52
sixty in this time span or don't
14:55
run this function. Or.
14:57
Run of that most once every one
14:59
minute, you know. and that kind of
15:01
stuff can be really, really funky. Are
15:03
retrying is another one? There's there's libraries
15:06
out there for run this promise And
15:08
if it fails, retry it. Up
15:10
to six times and if so then
15:12
finally reject and having that are built
15:15
in is really really nice. Guy.
15:17
Not, I mean it's funnier a I have
15:19
used. Throttling. In denouncing.
15:22
Pennies me these p tools before he
15:24
are always raping for me. it's it's
15:27
funny now. So
15:29
maybe ass? Maybe that's where you'll You'll have
15:31
to hit it. Or like. The
15:33
open a I eighty I only allows
15:35
you to. Run at.
15:38
A. Certain amount per minute mans yes
15:41
sometimes these a p eyes or returns
15:43
you how many calls you have left
15:45
and and when you're call amount refreshes
15:47
and if that's the case I'll just
15:49
look at the header and say or
15:51
eight if i'm out of cause. Throw.
15:55
A five hundred milliseconds wait, wait in there,
15:57
you know, and then and then fire and
15:59
off. I. If that's
16:01
not the case, they don't tell you how many are allowed.
16:03
they only tell you if you can't run it. If that's
16:05
the case, then you have to like. Use. One
16:08
of these libraries said and put in the hard
16:10
limits so that it won't run it to too
16:12
frequently. Type script and
16:14
promises. This last thing we have here
16:17
is just. How to use
16:19
promises and and script right? Because prices
16:21
are a generic in tights. Yep, it's
16:23
it's built in and your spouse and
16:25
see that intercepts it's promise. Angle.
16:28
Brackets and then the actual type of
16:30
the value that you want. And if
16:32
you if you fetch something. With
16:34
a specific type you'll see it's promise, square
16:37
bracket, whatever. And if you put in a
16:39
way it in front of the it will
16:41
unwrap the promise and actually give you the
16:43
real type. Yes! And so to be clear,
16:45
the reason why you do that promise with
16:48
the brackets around it's that essentially saying hey,
16:50
this thing does return a promise. Of
16:52
in the promise itself will
16:54
return that type some exactly
16:57
so eventually resolve to that
16:59
amount and a couple times
17:01
I've needed to get the
17:03
type. From. A
17:05
function that returns a promise. And.
17:08
If that's the case, like you're
17:10
using like a a type of
17:12
a specific function. Sometimes.
17:14
The one I take the promise asked like you
17:16
want to unwrap it like this function returns a
17:18
promise that is of a user. Me: I don't
17:20
care about the promise part I want the type
17:23
of user of and if that's the case you
17:25
can wrap it in the awaited. Type
17:27
script helper in that will take the the
17:29
promise part off and and give you the
17:32
ah the axle type their. Promised
17:35
are all settled filtering. this is just
17:37
like as a tight script thing in
17:39
general and I bet there's a thief
17:42
six soon, but I have also been
17:44
saying this for awhile. Snip you have.
17:46
A an array int I skipped a you
17:48
try to filter it. By.
17:50
Default if you don't use any like
17:53
patching libraries or anything like as the
17:55
filter does not actually. Narrow.
17:57
The types for the items that you filtered it
17:59
and with. The knowing say you have you
18:01
added type guard to your filter to
18:03
accede tell types given I am and
18:05
filtering down and I run into that
18:07
a lot with promised are all settled
18:10
because it will return again. The facility
18:12
and the rejected values as you on
18:14
is just filter for. The
18:16
rejected to display some errors in want to
18:18
filter for the successes to display the data.
18:20
It's then you'll have to write a quick
18:22
little type guard and. There
18:25
are. Think. There's a type
18:27
called Promise. All settled results. Moon.
18:30
And you can read a type guard
18:32
that will check for as either the
18:34
reason or the status property on their.
18:37
whom. And lastly, there's no way
18:39
to type the rejected value of
18:41
a promise in that that's a
18:43
little bit of a pain as
18:45
well. That's it. Can be nice.
18:48
To. Use that. in the last episode
18:50
we talked about that I'm. Writing.
18:53
Like a rapper function that will do
18:55
collecting and give you a to both
18:57
error first date a second you can
18:59
extend not a little bit further. And.
19:02
Internally, do a type assertion and you can say
19:04
are I love. If. It does return
19:06
and error. You. Can use a.
19:09
Generic. To say this is what
19:11
the error will look like and that
19:13
is really nice because now you're not
19:16
doing the whole like if it's error
19:18
is an instance of error and or
19:20
is error has a message property and
19:22
aegis know exactly what the air type
19:25
is. My
19:27
of yes, I think that's it for
19:29
promises. Wild World I'm I'm impressed that
19:31
were able to get three episodes out
19:33
of this, but there's a lot of
19:35
funky stuff to learn about. Promises and.
19:37
It's it's good to know. Can you imagine
19:39
if he would have had to do this episode on. Promise.
19:42
Libraries before promises
19:44
omitted. Yeah. It
19:47
would have been brit. There's so much like with
19:49
the promise libraries back in that eight hundred like
19:51
map everything even in know das before. Like.
19:54
I like like the file system a p
19:56
I didn't have promise versions of it. he
19:58
had a like wrap their. The back based
20:00
if the eyes in. A
20:02
like you till that promise of I
20:05
i do not in it he I
20:07
I I get actually got to wait
20:09
until promises landed in the browser before
20:11
had the off deal with promises I
20:13
a disease call backs until that like
20:15
you know it's seventy hours it on
20:17
a certain yeah it's awesome or it
20:20
think survey for to new twist your
20:22
promise tips that's index of and would
20:24
love to hear them. Take.
20:26
To cease.
Podchaser is the ultimate destination for podcast data, search, and discovery. Learn More