The evolution of asynchronous javascript

Post on 08-Feb-2017

800 views 4 download

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!