The evolution of asynchronous javascript
-
Upload
alessandro-cinelli -
Category
Technology
-
view
800 -
download
4
Transcript of The evolution of asynchronous javascript
THE EVOLUTION OF ASYNCHRONOUS
JAVASCRIPT
@cirpo
now & later
ASYNCRONY
the core of asynchronous programming is the relationship between
the now and later parts of your program
ASYNCRONY
how to express, manage and manipulate
program behaviours
over a period of time?
CONCURRENCY
CONCURRENCY
a way to structure a program
by breaking it into pieces
that can be executed independently
IS JS CONCURRENT?
A JS runtime contains a message queue, which is a list of messages to be processed.
To each message is associated a function.
When the stack is empty, a message is taken out of the queue and processed.
QUEUE
function f(b){ var a = 12;
return a+b+35; }
function g(x){ var m = 4;
return f(m*x); }
g(21);
STACK
function f(b){ var a = 12;
return a+b+35; }
function g(x){ var m = 4;
return f(m*x); }
g(21);
1 foo gets called
STACK
function f(b){ var a = 12;
return a+b+35; }
function g(x){ var m = 4;
return f(m*x); }
g(21);
2 first frame is created containing foo and local variable
1 foo gets called
STACK
function f(b){ var a = 12;
return a+b+35; }
function g(x){ var m = 4;
return f(m*x); }
g(21);
2 first frame is created containing foo and local variable
1 foo gets called
3 when foo calls bar, a second frame is push on top of foo, containing bar
arguments and local variables
STACK
function f(b){ var a = 12;
return a+b+35; }
function g(x){ var m = 4;
return f(m*x); }
g(21);
4 when bar returns, the top frame element is popped out of the stack
(leaving only foo call frame)
STACK
function f(b){ var a = 12;
return a+b+35; }
function g(x){ var m = 4;
return f(m*x); }
g(21);
5 When foo returns, the stack is empty
4 when bar returns, the top frame element is popped out of the stack
(leaving only foo call frame)
STACK
EVENT LOOP
JS IS NON BLOCKING
events
eventloop
net
filesystem
…
event queue thread pool
JS unlike a lot of other languages, never blocks
Handling I/O is typically performed via events and callbacks
When the application is waiting for an IndexedDB query to return or an XHR request to return, it can still process other things like user input
JS IS NON BLOCKING
Node.js is great for Input/Output processing but not optimised for CPU-bound work like performing a large amount of calculations.
JS IS NON BLOCKING
Up until recently (ES6), JS itself has actually never had any direct notion of asynchrony
built into it
JS runs inside a hosting environment (the browser/nodejs)
The event loop is handled by it
IS JS CONCURRENT?
goroutinesprocesses
IS JS CONCURRENT?
JS IS SINGLE THREAD
SORT OF …
BUT THE HOSTING ENVIRONMENT CAN USE
MULTI THREADFOR I/O OPERATIONS
most devs new to JS have issues with the fact that later doesn’t happen strictly and immediately after now
ASYNCRONY
tasks that cannot complete now are, by definition, going to complete asynchronously
and thus no blocking behaviour as it might intuitively expect or want.
ASYNCRONY
ASYNCRONY
ASYNC IS GREAT
BUT CAN BE HARD
SEQUENTIAL BRAIN
SEQUENTIAL BRAIN
put aside involuntary, subconscious, automatic brain functions
we are not multitasker
SEQUENTIAL BRAIN
As soon as we introduce a single continuation in the form of a callback function, we have allowed a divergence to form between how our brains work and the way the code will operate
can we do that?
yes… but we are blocking
WHEN YOU BLOCK,
YOU “PULL” A VALUE
CALLBACK
PIRAMID OF DOOM!
CALLBACK HELL!
BULLSHIT
HOW TO AVOID POD
HOW TO AVOID POD
ASYNC CALLBACK
ASYNC CALLBACK
=
ASYNC CALLBACK
PUSH
=
LOSS OF CONTROL
FLOW
LOSS OF ERROR
HANDLING
INVERSION
OF
CONTROL
“Don't call us, we'll call you”
INVERSION OF CONTROL
INVERSION OF CONTROL
what if it’s a third party call not under our control?
INVERSION OF CONTROL
INVERSION OF CONTROL
what if it’s never called?
INVERSION OF CONTROL
what if it’s never called?
what if it’s called too early?
INVERSION OF CONTROL
what if it’s never called?
what if it’s called too early?
what if it’s called too late?
meh.
HOW CAN YOU TELL IF
IT’S AN
ASYNC CALL?
meh.
Callbacks are the fundamental unit of asynchrony in JS.
But they’re not enough for the evolving landscape of async programming as JS
matures.
I <3 callbacks
PROMISES
PROMISES
It allows you to associate handlers to an asynchronous action's eventual success value or
failure reason.
This lets asynchronous methods return values like synchronous methods: instead of the final value,
the asynchronous method returns a promise.
A promise represents a proxy for a value not necessarily known when the promise is created.
PROMISES
http://ecma-international.org/ecma-262/6.0/#sec-jobs-and-job-queues
PROMISESPromises are now the official way to provide async return values in both JavaScript and the DOM.
All future async DOM APIs will use them, and many already do, so be prepared!
PROMISES
pending: initial state, not fulfilled or rejected
fulfilled: the operation completed successfully
rejected: meaning that the operation failed.
PROMISESalways async
returns a promise
handled once
thenable
PROMISES
A promise must provide a then method to access its current or eventual value or rejection
reason
.then()
PROMISES
.then(onFulfilled, onRejected)
PROMISES
can return a promise
.then()
PROMISES
.then()
.then()
.then()
PROMISES
.catch()
Talk is cheap, show me the code
PROMISES
PROMISES
PROMISES
inversion of control
async or sync?
error handling
control flow
WIN!
BUT …
PROMISE HELL!
AVOID PROMISE HELL!
AVOID PROMISE HELL!
DON’T USE PROMISES
FOR CONTROL FLOW
YOUR CODEBASE THEN
BECOMES
PROMISE DEPENDANT
USING PROMISES
EVERYWHERE
IMPACTS ON THE DESIGN
TO PROMISE OR TO
CALLBACK?
IF YOU HAVE A
LIBRARY, SUPPORT BOTH
SINGLE VALUE
SINGLE RESOLUTION
BAD FOR STREAMS
SINGLE RESOLUTION
PERFORMANCES
PERFORMANCES
Promises are slower compared to callbacks
You don’t get rid of callbacks, they just orchestrate callbacks in a trustable way
PERFORMANCES
Promises are slower compared to callbacks
You don’t get rid of callbacks, they just orchestrate callbacks in a trustable way99.9% of the time you
won’t feel it
PROMISES
WHAT IF WAITING WERE
JUST AS EASY AS
BLOCKING?
GENERATORS
GENERATORS
A new type of function that does’t not behave with the run-to-completion behaviour
GENERATORS
GENERATORS1 constructing the iterator, not executing
GENERATORS1 constructing the iterator, not executing
2 starts the iterator
GENERATORS1 constructing the iterator, not executing
2 starts the iterator
3 pause the iterator
GENERATORS1 constructing the iterator, not executing
2 starts the iterator
4 resume the iterator
3 pause the iterator
GENERATORS1 constructing the iterator, not executing
2 starts the iterator
4 resume the iterator
3 pause the iterator
GENERATORS
with the yield where are pausing
GENERATORS
A.K.A BLOCKING!
with the yield where are pausing
GENERATORS
GENERATORS
iterator is just one side…
GENERATORS
the other side is an observable
GENERATORS
GENERATORS
GENERATORS
GENERATORS
GENERATORS
we can block!
we can pull values
we can push values
GENERATORS
GENERATORS
+
PROMISES
the iterator should listen for the promise to resolve
then either resume the generator with the fulfilment message (or throw an error into the generator with the rejection reason)
GENERATORS + PROMISES
GENERATORS + PROMISES
GENERATORS + PROMISES
GENERATORS + PROMISES
GENERATORS + PROMISES
npm install co
BUT…
ES7ES2016
to the rescue!
async/await
async/await
npm install -g babel-cli
babel a.es6 -o a.js
node a.js
//add it either to .babelrc or package.json{ "plugins": ["transform-async-to-generator"]}
npm install babel-plugin-transform-async-to-generator
STREAMS
callbacks
async/await
CHOOSE YOUR CONCURRENCY MODEL
A big thanks toKyle Simpson (@getify)
github.com/getify/You-Dont-Know-JS
@federicogalassi
@unlucio
… and my mentors
slideshare.net/fgalassi
slideshare.net/unlucio
@loige
@mariocasciaro
youtube.com/watch?v=lil4YCCXRYc
@cirpo
Dev lead at
github.com/cirpo
http://sainsburys.jobs
THANK YOU!