►
From YouTube: Broken Promises - James Snell, NearForm
Description
Speakers: James Snell
When a customer comes to us with a complaint that their code is running slowly, our first question has become, "Are you using Promises?". When they predictably tell us yes, our response has become, "You're likely using them wrong".
In this talk, we'll discuss the various ways Promises are abused. We'll talk about why that ends up needlessly slowing Node.js applications down. And we'll talk about how to use Promises correctly, the way they were intended to be used.
Expect code, opinions, and colorful charts.
A
A
The
thing
I'm
working
on
is
the
quick
implementation
that
for
beacon
was
talking
about
yesterday,
but
in
your
form
one
of
the
things
that
we
do
is
you
know
we
have
a
lot
of
customers
that
come
to
us
and
ask
us
so,
but
you
know,
saying:
hey
our
stuff
is
slow.
Come
help
us
figure
out
why
our
wire
code
is
slow,
and
over
the
past
couple
of
years
we've
we've
come
to
ask
one
very
specific
question:
when
a
customer
comes
to
us
and
says
hey
our
stuff
is
slow.
A
The
first
question
is:
are
you
using
promises
all
right
and
if
they'd
say
yes,
all
right,
our
response
right
away
is
you're
using
them
wrong.
Well,
you
know
you
haven't
even
looked
at
our
code,
get
there
enough
to
you're
using
them
wrong
all
right.
So
what
we
have
found
in
the
overwhelming
majority
of
cases
when
anybody
is
using
promises,
they
are
it's
some
way,
it's
some
level
using
them
incorrectly,
so
that
it's
the
inspiration
of
this
talk
is
basically
all
the
ways
that
we
have
seen:
customers
using
promises,
incorrectly
and
kind
of
breaking
down.
A
Why
why
it's
incorrect
kind
of
you
know
how
to
how
to
avoid
those
issues?
Now
one
example:
they
got
caught
up
with
a
customer.
They
are
having
some
really
poor
response
times
on
their
API
I
decided
to
do
a
30
second
benchmark
on
one
path
of
their
code
right,
so
we're
basically
just
sending
the
same
request
over
and
over
and
over
again
against
their
server
executing
a
single
branch,
a
single
path
within
that
30
second
benchmark.
They
were
allocating
30,000
promises.
A
Okay,
I'll
explain
why
in
just
a
little
bit,
but
there
are
a
few
other
examples
like
that
that
I
will
share
with
you
all
right.
So
promises
are
powerful.
Yes,
they're
there
in
a
language,
you
really
have
to
understand
how
how
they
function
and
what
their,
what
their
purpose
is
right
when
to
use
them,
and
especially
when
not
to
use
all
right
everything
that
I'm
going
to
show
you
is
based
on
what
we
have
seen
actual
customers
do
in
production
code.
Alright,
so
you
know
some
of
the
examples
you
know.
A
I've
I've
simplified
the
examples,
I'm
not
going
to
say
what
you
know
who's.
You
know
what
customers
and
what
companies
are
doing,
what
right
so
I
completely
anonymous
it.
Some
of
the
examples
may
look
a
bit
contrived,
but
they
are
based
on
stuff
we've
actually
seen
in
the
out
of
the
real
world,
but
first
I
want
to
do
a
puzzle.
I've
notice,
a
few
times
this
code
prints
a
message.
It's
a
secret
message
right.
Without
writing
the
code.
Try
to
figure
out
what
the
message
is.
A
You
could
you
know
without
trying
to
copy
down
here
you
can
scan
the
the
QR
code,
I'll
also
post
this
on
on
my
Twitter
feed
after
this.
But
you
know
the
task
is:
try
to
figure
out
what
the
messages
without
running
all
right.
What
this
code
is
doing
is
using
all
the
various
ways.
You
can
schedule
a
synchronous
activity
and
note,
so
we
have
next
ticks.
We
have
immediate.
We
have
some
promises
in
there
key
micro
tasks
right,
so
this
will
print
a
message
out
if
you
figure
it
out
again
without
running
the
code.
A
Let
me
know
alright,
so
I'll
give
you
a
moment
to
folks
scan
the
QR
code
there,
okay,
alright!
So
the
reason
I
like
to
start
with
this
particular
example.
Is
it
because
it
emphasizes
the
fact
that
you
really
need
to
understand
when
code
is
being
executed
within
within
a
note
or
then
javascript
in
general?
Alright,
so
we
all
know,
node
is
a
JavaScript
platform.
Right
is
JavaScript
running
all
of
the
time.
In
note,
all
right,
no
all
right.
So
let
me
show
you
a
quick
example
of
this.
A
So
if
I
do
a
set
interval
right,
I'm
going
to
set
it
for
you
know
about
a
second.
Actually
let
me
let
me
change
this
a
little
bit.
We're
gonna
set
it
to
run
every
500
milliseconds
we're
gonna.
Have
this
thing,
do
a
for
loop
and
then
do
a
console.log
very,
very
simple
application,
so
I'm
gonna
run
this
I'm
gonna
turn
on
trace
events
and
we're
gonna
turn
v8
a
nation
cooks.
This
is
basically
give
us
some
insight
into
what
is
happening
under
the
covers
on
this
and
they're
going
to
run
this
okay.
A
So
it's
just
gonna
iterate
through
five
times.
That's
going
to
end
up
creating
this
file.
This
node
Trace
got
one
file.
Let's
pop
back
over
chrome
tracing
is
it's
a
utility
built
into
a
Chrome
browser,
allows
you
to
be
a
trace
event,
log
data
generated
by
node
or
by
the
browser.
So
let's
load
this
thing
up.
A
This
file
that
we
just
created
this
node
underscore
trace,
might
be
a
little
bit
hard
to
read
there
from
the
back,
but
these
pink
boxes
right
here
are
the
plate
other
times
when
node
and
v8,
or
actually
executing
JavaScript
the
blank
spaces
between
or
times
when
no
JavaScript
is
being
run.
That
is
times
when
the
node
event
loop
is
doing
other
things.
In
this
case.
It's
waiting
for
that
event
for
that
timer
to
fire
right.
A
So
within
that
time,
the
event
loop
is
actually
spinning
right,
but
while
the
pink
boxes
are
executing
the
event,
loop
is
not
spinning
the
event
loop
is
completely
blocked.
Okay,
now,
when
we
say
schedule
a
synchronous
activity,
what
we're
talking
about
is
in
one
of
the
pink
boxes,
triggering
some
action
that
is
not
going
to
complete
until
another
pink
box
starts.
A
Okay,
you
know
on
this.
So
basically
like
we
want
to
do
a
file.
Read
right
file.
Reads
a
node
happen
in
a
in
a
thread
pool
so
we
trigger
the
file.
Read
it's
gonna
go
off
and
read
the
file
in
a
separate
thread
when
that
file
man
data
is
available.
After
the
event,
loop
turns
right,
it'll
see.
Okay,
that
data
is
available.
Now
then
it'll
start
executing
JavaScript
again
all
right
with
a
promise.
You
never
ever
want
to
create
a
promise
that
resolves
within
the
same
execution
block
that
it
was
created.
A
If
you
can
avoid
it
all,
right
and
I
say
you
can
wait
if
you're
using
like
promise
not
resolve
right.
That
is
explicitly
a
synchronous
promise
right
with
promises
that
you,
you
know,
don't
ever
use
them
where
they
resolve.
In
the
same,
you
want
to
use
it
to
you
know
when
you
create
it,
you're
scheduling
some
asynchronous
activity,
it's
happening,
optimator
vent
loop
and
then
it's
going
to
come
back
and
execute
later
on
right.
That's
key!
That's
that's!
That's
number
one
and
I'll
get
into
a
little
bit
about
why
that
is
a
little
bit
later.
A
A
A
No
I
mean
you
can
do
a
try-catch
inside
this
thing,
but
then
you
know
your
error
happening
is
limited
in
inside
that
you
can't
bubble
it
out
anywhere
right.
So,
with
this
case,
what
you
end
up
with
is
an
unhandled
rejection.
You
can't
actually
catch
any
errors
thrown
within
that
async
function
outside
of
that
of
that
function
right,
we
see
this
in
all
kinds
of
places.
So
if
we
take
a
look
at
event,
you
meter
people,
love
passing
async
functions
to
you
know
to
handle
events
now
just
recently
within
node.
A
Coral
I'll
show
an
example
of
this
later.
We
just
had
a
new
feature,
landed,
called
capture,
rejections
that
makes
event
emitter
aware
of
promises,
but
most
cases
if
you're
talking
about
event
emitter.
If
you're
talking
about
callback
functions,
these
things
are
not
expecting
promises,
they
are
not
expecting
async
functions
and
they
do
not
know
how
to
handle
them
correctly
and
what
you're
going
to
end
up
with
our
cases
where
you
are
either
you
know,
you
know.
A
At
the
best
case,
you
have
an
unhandled
rejection
at
the
worst
case,
you
have
memory,
leaks,
resource
leaks
and
this
case
we
would
be
leaking
a
file
descriptor
all
right.
That
would
never
end
up
getting
closed.
If
there's
an
error
somewhere
in
here,
you
end
up
with
asynchronous
context:
it's
not
propagated
properly
down
through
all
of
your
callbacks
or
all
your
promises.
All
right.
You
can
end
up
with
orphans
promise
chains
they
have.
You
have
no
way
of
handling
all
right
and
all
kinds
of
other
kind
of
nastiness.
A
You
know
and
we
actually
get
into
bass
with
this.
You
know
you
know
you
know
Matteo
Colinas
gotten
on
Twitter
and
said:
don't
mix,
callbacks
and
promises
together,
and
then
we
actually
end
up
with
debates
on
this
honest
website.
No,
it's
no
problem.
We
can
show
specific
examples
here
of
them
of
memory.
Leaks
happening
right
me,
I
have
one
in
here,
I
mean
look
at
this
okay,
so
right
here
we
open
a
file
and
it's
just
kind
of
the
local
file.
We
read
it.
A
We
open
two
file
descriptor,
we,
you
know
we
have
some
error
handling
in
there
right.
Then.
Let's
call,
you
know
a
function,
you
know
you
know
happen
to
be
something
that
you
know.
The
reference
is
not
resolved
right
in
this
case
that
async
function
is
going
to
throw
that
unhandled
rejection
and
that
FS
close
is
never
going
to
fire.
Now,
a
lot
of
times,
we'll
have
a
you
know,
promise
or
a
process
on
on
handled
rejection
to
do
some
logging
all
right.
A
So
maybe
your
your
you
know,
you'll
see
a
nun
held
rejection
or
an
error
in
your
logs,
but
the
actual
file
descriptor
itself
never
actually
gets
closed.
We
see
this
all
of
the
time
now
it's
possible
to
get
around
this.
You
use
you
know
a
try-catch
in
this
function,
use
it
finally
in
here
to
close
it,
but
most
of
the
time
developers
completely
forget
to
do
that
right.
A
This
is
one
of
the
most
common
issues
that
we
see
all
right.
So
this
is,
you
know,
and
these
are
things
that
are
that
are
that
are
easily
checked
the
simple
rule
on
this:
don't
pass
an
async
function
or
promise
to
a
callback
that
does
not
expect
it
period.
Just
don't
do
it
all
right
now.
Another
weird
one
that
we've
been
seeing
lately-
that's
just
bizarre.
A
Are
people
mixing
new
promise
in
async
functions
right,
the
the
the
oddest
one
of
this
that
I've
seen
recently
was
a
wait
new
promise.
There
was
past
an
async
function
and
then
the
resolved
it
was
resolved
away
from
me
right,
I
still
don't
quite
know
what
they
were
trying
to
accomplish
right.
It
was
not
what
they
expected
all
right.
Let
me
ask
you
this:
if
I
have
a
regular
function
like
this,
a
new
promise
and
I
throw
in
here
right,
what's
gonna
happen.
Is
that
going
to
get
caught
or
is
gonna
be
a
thrown
immediately?
A
It's
immediately
thrown
a
lot
of
folks
say
anything.
That's
any
error
that
somewhat
thinner
promise
is
going
to
get
caught
by
the
catch
handler.
It
is
not
right.
It's
only
caught.
If
it
happens
in
a
you
know,
dot
then,
or
a
dot
catch
right.
You
know
in
one
of
the
in
the
chain
the
function
that
is
passed
to
the
promise
itself.
That
will
throw
immediately.
When
is
this
function
executed
immediately
right.
There
is
a
common
misconception,
particularly
among
developers
that
are
coming
from
Java
and.net
environments,
that
new
promise
is
equivalent
to
new
threat.
A
Right
there's,
you
know
it's
it's
a
very
common
misconception.
I
I
I
had
to
sit
down
and
prove
it
for
I
think
it
was
about
45
minutes
go
through
a
proof
for
a
customer
that
we
were
at,
but
with
a
developer
team.
They
were
absolutely
convinced
that
new
promise
was
was
running
in
parallel
right,
just
kind
of
magical,
new
threats.
There's
a
huge
amount
of
misconception
out
there
about
how
this
works
right.
So
this
error
it's
going
to
get
thrown
immediately.
A
A
You
think
that's
gonna
handle
it.
There's
a
they're
coming.
You
know
believe
that
yeah,
if
you
pass
an
eight,
a
promise
to
this
thing,
you're
worth
it
and
promises
it
will
not
catch
it.
You
got
a
nun
that'll
projection.
The
cash
handler
cannot
see
this
in
any
way,
but
we
are
seeing
this
more
and
more
and
more
I
think
we've
seen
this
and
I
think
three
or
four
customer
projects
just
over
the
past
couple
of
months.
All
right-
and
this
is
based
on
a
belief
that
hey
async
functions
are
great.
A
Let's
use
them
everywhere,
no
like
just
just
no
at
all
all
right,
so
we
have
that
one
very
important.
Just
you
know
you
have
to
be
very
careful
about
where
promises
are
actually
being
used
you
they
are
a
very
specific
tool
that
are
used
only
for
scheduling
a
synchronous
activity
and
waiting
for
the
result
of
that
activity
right,
but
as
we'll
see
as
we
go
along,
there's
lots
of
other
ways
that
people
are
abusing
these
things
all
right.
So,
let's
move
forward
here
all
right.
A
So,
if
we're
not
going
to
be
passing
an
async
function
to
a
callback,
if
we
are
not
supposed
to
be
mixing
these
things,
how
do
we
actually
get
by
it
right?
The
answer
is:
if
you're
going
to
be
using
promises,
go
all
in
on
promises.
If
you're
going
to
be
using
callbacks,
just
do
everything
callbacks
right.
If
you're
going
to
be
mixing
them,
it's
it
actually
gets
very
complicated.
I'll
show
you
an
example
of
kind
of
doing
it
right
and
I'll
show
you
how
complicated
it
gets.
A
This
in
this
case
we're
fully
we're
using
promises
throughout
the
entire
player,
so
we're
using
the
promise
flight
version
of
the
FS
module
right.
So
we
have
a
promise
I'd
version
of
open
that
we
can
await
what
this.
What
this
version
of
open
gives.
You
is
a
file
handle
object
that
will
automatically
close.
If
you
forget
to
do
it
now,
it'll
give
you
a
warning,
but
it
will.
It
will
go
ahead
and
clean
up
after
itself.
A
If
you
forget
to
do
it,
try
to
avoid
that
memory
leak,
but
it'll
get
you
know,
it'll
be
noisy
when
it
doesn't
it'll,
say
hey.
You
should
be
explicitly
closing
this
thing.
Do
that
next
time,
all
right,
so
this
is
a
much
safer
way
of
doing
this.
Error
handling
is
consistent
throughout
and
we're
properly
propagating
errors
in
context
here.
Alright,
so
just
as
a
general
rule
do
not
mix
callbacks
promises
do
one
or
the
other
all
right.
Now
it
is
possible
I
guess
it
took
inviting
them
becomes
much
more
complicated.
Alright.
A
So,
in
this
particular
case,
I'm
creating
the
promise
I
have
the
resolve,
reject
I,
have
two
callbacks
two
nested
callbacks
that
are
happening
right,
I'm
having
to
propagate
the
reject
through
those
different
levels.
So
this
is,
you
know
if
you've
heard
a
callback
he'll.
This
is
you
know,
callback
and
promise
he'll,
and
it
just
gets
even
nastier
right
and
the
problem.
The
reason
this
is
nasty
is
that
promises
and
callbacks
operate
on
two
completely
different
abstraction
models.
A
Right,
yes,
both
involves
scheduling,
async
activity,
but
how
they
are
resolved,
how
they
you
know
in
the
execution
model
or
are
entirely
different
and
incompatible
to
one
another,
so
you
have
to
kind
of
bunch
them
together
in
order
to
get
them
to
work
now,
utilities
like
util
dot
promise
if
I,
which
will
take
a
callback
function
and
wrap
it.
It
does
quite
a
bit
of
work
under
this
under
the
covers
to
make
sure
this
is
done
correctly.
Alright,
so
make
use
of
util
promise
file.
I
have
a
few
examples
of
that
in
here.
A
This,
like
you,
can
do
you
want
a
promise
flight
version
of
set
timeout
and
you
can
do
let's
say
sleep
equals
util
promise.
If
I
set
timeout
right
and
then
from
there
and
like
you
know,
sleep
actually
becomes
promise
fine
right,
you
can
do
whatever
right,
okay
and
that,
actually
you
know
it
won't
block
the
event
loop.
It's
just
a
timer,
that's
happening
under
the
covers,
but
it's
been
wrapped
in
a
way
that
it
does
proper
propagation
of
errors,
all
right
event,
emitter.
This
was
mentioned
in
giuseppe's
talk
earlier.
A
If
you
pass
in
the
capture
rejections
now,
this
isn't
in
a
in
a
node
release.
Yet
so
it's
not
gonna
work
with
the
version
of
node
I'm
using
here,
because
I'm
using
a
release
version,
but
this
error
fight.
You
know
it
won't
work
properly
if
I
run
example,
but
what
this
will
do
is
if
you
pass
the
basic
function
in,
if
it
errors
it
will
cause
a
error
event
to
be
emitted
properly
right,
it
won't
be
hidden
by
the
the
promise
chain.
Okay.
So
there
are
ways
to
do
this
correctly.
A
It's
just
complicated
and
difficult,
and
you
know
Matteo
clean
and
his
talk
yesterday
made
the
point
that
you
might
spend
a
ton
of
time
in
your
code,
doing
it
correctly,
but
I
can
guarantee
you
there's
somebody
on
your
team
or
another
team,
the
arrogant
that
will
just
do
it
wrong
right.
So
it's
very
difficult
to
do
this
consistently
and
we
have
seen
this
time
and
time
and
time
again
where,
especially
with
people
not
handling
errors
correctly,
that
it
just
falls
down
okay,
so
alright!
So
let's
move
on.
Let's
see
here's
the
venue
mitr
all
right.
A
The
reason
we
have
to
do
that
in
a
process
next
tick
is
because
emit
is
asynchronous
function
when
it
is
operating
when
you
call
it
in
this
context,
from
anathan
an
async
function,
if
error
handling
is
bound
to
that
promise
right.
So
if
you
throw
it's
just
gonna,
be
same
part
of
the
same
cop
throat
right
and
you'll
end
up
with
a
an
unhandled
rejection,
so
next
chick
allows
you
to
escape
that
all
right.
It
allows
you
to
escape
the
promise
right.
A
A
Okay,
so
the
other
this
one's
fun.
How
many
of
you
have
seen
long
then
chains
in
your
code
right,
denne,
denne,
denne,
dot,
then
the
worst
one
of
these
that
I've
seen
was
about
fifteen
or
sixteen
of
these
chained.
You
know
it's
in
a
module,
that's
you
know
actually
pretty
popularly
used.
We
recommend
now.
A
If
we
see
it
just
don't
just
don't
so
use
it
and
what
we
typically
find
when
people
have
these
long
dot
n
chains
is
that
they're
being
used
or
basically
make
the
code
readable,
okay
and
they're
typically
end
up
being
used
for
flow
control
of
synchronous
code.
So
in
this
particular
case
we
see
notices
this
one's
pretty
contrived,
but
it
you
know
again
see
this
all
the
time
yeah
we
have
two
upper
to
lower
reverse
we're,
basically
just
isolating
functionality
into
individual
functions
and
then
we're
gonna
chain
them
together.
You
know
with
with
dense.
A
This
is
absolutely
pointless.
All
of
this
code
is
resolved.
Synchronously
right,
it's
all
going
to
be
executed,
synchronously,
it's
all
going
to
be
blocking
the
event
loop
in
one
turn
right.
These
promises
are
going
to
get
resolved
in
the
the
microbe
task
queue.
That's
the
best
part
of
all
this
that
excuse
to
the
den
and
catch
handlers
will
actually
be
executed,
synchronously
immediately
following
the
execution,
you
know
the
wrote
resolution
these
promises.
There
is
no
asynchronous
activity
happening
here
at
all.
A
This
is
probably
cardinal
sin
number
one
with
with
promises
all
right,
but
we
see
this
all
of
the
time
and
every
single
time
it's
because
it
makes
it
more
readable
right,
you
might
make
it
more
readable,
but
it's
going
to
absolutely
kill
your
performance.
We've
seen
this
code,
like
this
we've
seen
it
take
coat
down.
Maybe
60
70
percent
performance
toys
just
because
they're
doing
this
kind
of
stuff
all
right
to
make
it
even
worse.
People
will
do
things
like
make
these
async
functions
right,
which
just
causes
even
more
out
promise
allocations.
A
When
you
await
an
async
function,
do
you
know
how
many
promises
are
created
just
by
cut
you
know,
if
you
just
a
empty
async
function,
that
does
nothing
else.
If
you
await
that
function,
it
creates
three
promises
every
time,
no
matter
what
else
it's
do
it
right.
Every
time
you
await
an
async
function,
all
right,
so
you
need
to
be
aware
of
what
you're
actually
allocating
here
and
and
for
what
purpose,
you're
actually
allocating
those
four
all
right.
So
for
this
you
know
it's
it's
simple!
A
If
you,
if
you
absolutely
need
that
getdata
to
return
a
promise
right,
go
ahead
and
resolve
the
promise
synchronously
right
and
use
promise
that
resolved.
That's
what
it's
there
for
that's
the
intent
run
your
code
synchronously
and
save
yourself.
The
trouble
of
all
those
additional
promise
allocations
all
right.
There
is
no
other
there's.
No
other
correct
way
of
doing
this
right,
do
not
wrap
sync
purely
synchronous
code
and
a
promise
in
a
promise
chain
of
dense.
The
only
place
you
should
have
purely
synchronous
code
is
in
the
final
then
handler.
A
That
is
the
only
place
all
right
all
right,
let's
keep
going
loop's.
Oh,
these
are
fun.
Passing
an
async
function
to
a
functional
loop
like
for
each
or
map
or
filter.
All
right.
The
example
I
told
you
at
the
beginning
where
the
people
were
creating
30,000
promises.
This
is
how
they
were
doing
it.
They
were
parsing
a
1
Meg
JSON
file,
iterating
synchronously
over
every
field
in
that
file,
creating
a
promise
for
every
field,
not
just
a
promise,
a
promise,
change
for
every
field,
right
and
majority
of
those
promise
chains
for
we
resolved
synchronously.
A
So
json.parse
is
synchronous
code
iterating
through
the
synchronous
loop,
allocating
thousands
of
promises
in
a
you,
know,
synchronously
and
then
resolving
them
all
synchronously.
Now,
let's
see
if
you
know
why
this
is
a
bad
thing.
Let
me
show
you
so
we're
gonna
go
ahead
and
run
no
to
get
your
run.
Note
again
with
our
trace
events.
A
All
right
so
we're
gonna,
let
this
run
for
a
bit
and
all
this
code
is
doing
taking
you
know,
setting
a
series
of
numbers
and
then
inverting
the
values
right.
We've
got
about
a
thousand
of
them
in
there
all
right,
so
it's
going
to
create
that
trace
event
file
again.
So
how
many
promises
do
you
think
were
created
during
that
bring
that
operation?
A
A
So
that
how
many
promises
do
we
think
you
said,
like
you
know
five
actually
there's
about
eight
thousand,
and
we
can
see
that
here.
Every
single
one
of
these
lines
is
a
promise
several
promises,
so
these
are
all
being
created
in
a
synchronous,
loop
right.
We
really
the
the
the
iteration
was
a
thousand
iterations
right,
so
we
have
about
eight
thousand
promises
that
were
created
over
that
synchronous
iteration.
Now,
how
do
we
know?
It
was
all
synchronous,
let's
go
all
the
way
down
here
at
the
bottom,
and
we
see
this
v8
execute
block
right.
A
So
this
is
a
synchronous
code.
If
we
go
back
to
the
trace
event,
log,
every
single
one
of
those
promises
was
allocated
synchronously
within
the
exact
same
block
right
now
in
these
particular
promises
we
do
have
a
timer
right,
so
it
is,
they
are
scheduling
a
synchronous
activity,
but
we're
still
allocating
all
those
promises
all
at
once
and
there's
code
running
in
those
sync.
Let's
go
running
in
each
of
those
that
is
causing
this
massive
event.
Loop
block.
So
during
this
time
that
event
loop
can't
do
anything
else
right.
A
We
have
one
example
of
a
customer
they
were
received
was
receiving
a
whopping
four
requests
per
second
all
right.
What
was
it
doing?
They
were
parsing
very
complex
graph,
QL
queries
that,
on
the
back
end
were
talking
about
ten
or
fifteen
back-end
services
right
the
way
the
graph
QL
implementation
in
Apollo
works.
It's
very
promise
heavy
uses
these
long
promise
chains.
It
goes
off
and
parses
the
query
locks
the
query
figure.
A
You
know
figures
out
an
execution
plan
for
the
query
right
and
then
it
kind
of
goes
through
and
and
executes
the
backend
queries
and
then
reassembles
the
data
right.
Well,
they
were
receiving
a
large
number
of
timeout
errors
as
they
were.
There
is
they're
winning
this
thing
and
that's
actually.
Why,
then,
what
was
killing
their
their
their
throughput?
What
was
happening
is
the
backend
services
services
were
receiving
their
queries
and
they
were
returning
data
back
right
now.
The
way
that
the
event
event
loop
works.
A
When
there's
data
that's
been
returned,
it
sits
in
a
queue
until
the
event
loop
turn
and
it
can
say:
hey,
there's
data
available,
I'm
gonna
go
ahead
and
fire
off
the
callbacks
associated
with
those
right,
but
timeout
timers,
fire
first,
so,
okay,
so
the
event
loop
was
being
blocked.
Long
enough,
it
was
sending
the
request.
The
backend
servers
were
returning
the
data,
but
by
the
time
the
event
loop
turned
over
its
a
took
too
long.
A
So,
even
though
the
data
is
sitting
there,
the
the
system
would
crash
and
they
were
only
getting
four
requests
per
second
through
and
their
solution
to.
That
was
to
throw
a
thousand
more
servers
in
it.
I
mean
okay
that
works
I
guess,
but
whenever
you're
creating
promises
in
a
synchronous,
loop
just
don't
or
keep
your
iterations
very,
very
small
right,
there's
an
old
rule.
You
know:
don't
create
a
closure
all
right
limit.
The
number
of
allocations
are
doing
in
a
loop,
the
same
thing
here.
A
Every
time
you
create
a
promise
right,
you're
allocating
something
on
the
heap
all
right.
So
we
just
created
8,000
objects
on
the
heat
right
and
a
synchronous.
If
it's
just
not
something
you
want
to
do,
you
have
to
be
aware
of
what's
happening
when
you're
creating
these
promises
all
right
so
another
interesting
this,
this
one
just
qualifies
under
I
I,
don't
have
any
idea
what
they're
doing
or
why
right
return
await
new
promise.
Async
resolve
pretty
soft
first
awake.
This
is
this
was
based
on
a
real
customer
example.
A
We
got
like
two
weeks
ago
right
now.
What
they're
doing
here
is
assembling
an
object
over
time
right
and
these
leave
a
wait
are
actually
going
off
in
doing
database
queries
right
and
what
they
want
to
do
is
if
one
of
them
dies,
they
don't
want
to
continue
right
so
they're,
not
they
don't
want
to
go
off
and
execute
all
these
things
in
parallel.
They
do
want
to
do
them
one
at
a
time,
so
they
figured.
Let's
spread
it
out.
This
way
where
they
came
up
with
this
return
await
new
promise.
A
A
Okay,
so
if
we
really
wanted
to
wait
on
it
right
and
do
these
things,
you
know
the
way
that
they
said
we
just
you
know,
get
this
right,
much
more
readable.
It
actually
makes
sense
you're,
not
using
strange.
You
know,
syntax
that
you
know
should
get
you
slapped
and
it
just
works
now,
in
this
case,
you're
still
waiting
to
six
hundred
milliseconds
for
everything
to
complete
right,
you're,
still
waiting
for
a
one
to
finish
first,
and
if
it
fails,
then
you'll
stop
right.
A
If
you
wanted
to
do
it,
if
you
really
did
want
to
do
it
in
parallel,
then
you
could
use
promise
all
and
goes
off
and
execute
these
things.
All
right,
quick
comment
on
pro
song
that
I'm
coming
up
to
you
know
you
know
running
out
of
time
here:
promise
all
wait
through.
You
know
everything
to
to
finish
right
behind
it'll
short
circuit
at
the
first
rejection
right.
What
happens
to
the
other
promises
if
one
of
those
rejects
what
happens
to
the
other
promises?
A
They
continue
a
lot
of
folks.
Don't
know
that
all
right,
especially
bad
when
they
use
when
you
use
promise
race
all
right
promise
race
is
the
first
one.
You
know
the
one
that
finishes.
First,
is
the
winner:
what
happens
if
the
other
one
is
taking
a
very
long
time
to
finish?
It
still
goes
and
still
blocks
your
event.
Loop
right,
so
you're
using
promise
race
actually
doesn't
actually
buy
you
very
much.
There
are
use
cases
for
it
in
the
browser.
A
A
node
is
just
gonna,
kill
your
performance
all
right,
so
let
me
see
yeah,
that's
essentially
it
I
can
go
back
here
to
the
slides.
We
have
some
basic
rules
to
follow
know
when
your
code
is
being
executed.
Right,
use,
trace
events,
if
you
use
the
trace
event
categories,
you
know
and
turn
on
the
v8
category.
You
will
see
exactly
when
javascript
is
running
right.
A
You
will
know
when,
when
it
you'll
know,
when
it's
not
running
all
right,
you
want
to
make
sure
that
you,
if
you
are
you
making
use
of
promises
that
you
are
spanning
those
barriers,
your
you
know,
your
promises
should
not
be
resolving
within
the
same
event.
You
know
this.
The
the
same
v8
execution
right
if
they
are
go
back
and
figure
out
what's
wrong
or
don't
use
a
promise,
they're,
alright,
don't
use
unexpected
promises,
just
don't
right
if
a
function
does
not.
A
If
you
do
not
know
that
it
is
designed
to
take
an
async
function,
do
not
pass
an
async
function,
you
know
again
avoid
mixing
promises
and
callbacks
use
one
or
the
other.
All
right,
don't
create
promises
and
loops
again
synchronous
promises
are
just
useless
and
do
not
use
long
Ben
chains
just
avoid
it
as
much
as
you
possibly
can
alright.
So
that's
it.
Thank.