steam learn: asynchronous javascript

31
6th of June, 2015 Asynchronous Javascript Common and useful patterns by Steven Rémot

Upload: inovia

Post on 07-Aug-2015

36 views

Category:

Software


3 download

TRANSCRIPT

Page 1: Steam Learn: Asynchronous Javascript

6th of June, 2015

Asynchronous JavascriptCommon and useful patterns

by Steven Rémot

Page 2: Steam Learn: Asynchronous Javascript

6th of June, 2015

Table of contents

1. Callbacks

2. Promises

3. Generators

Page 3: Steam Learn: Asynchronous Javascript

6th of June, 2015

Table of contents

1. Callbacks

2. Promises

3. Generators

Page 4: Steam Learn: Asynchronous Javascript

6th of June, 2015

Callbacks - Usage

function GameController() { var dirChangedCb = function () {};

this.onDirectionChanged = function (callback) { dirChangedCb = callback; };

document.addEventListener('keydown', function (event) { dirChangedCb(determineEventDirection(event)); });}

var gc = new GameController();gc.onDirectionChanged(function (direction) { hero.move(direction);});

Page 5: Steam Learn: Asynchronous Javascript

6th of June, 2015

Callbacks - Avoiding conflicts

function GameController() { var dirChangedCb = function () {};

this.onDirectionChanged = function (callback) { dirChangedCb = callback; };

document.addEventListener('keydown', function (event) { dirChangedCb(determineEventDirection(event)); });}

var gc = new GameController();gc.onDirectionChanged(function (direction) { hero.move(direction);});

gc.onDirectionChanged(function (direction) { enemy.reactTo(direction);});

Only one callback is saved

Page 6: Steam Learn: Asynchronous Javascript

6th of June, 2015

Callbacks - Avoiding conflicts

function GameController() { var dirChangedCbs = [];

this.onDirectionChanged = function (callback) { dirChangedCbs.push(callback); };

document.addEventListener('keydown', function (event) { for (var i = 0; i < dirChangedCbs.length; i++) { dirChangedCbs[i](determineEventDirection(event)); } });}

var gc = new GameController();gc.onDirectionChanged(function (direction) { hero.move(direction);});

gc.onDirectionChanged(function (direction) { enemy.reactTo(direction);});

Page 7: Steam Learn: Asynchronous Javascript

6th of June, 2015

Callbacks - Nested operations

function loadHero(loadingFinishedCallback) { http.get('/characters/hero.json', function (heroData) { loadingFinishedCallback({ data: heroData }); });}

Page 8: Steam Learn: Asynchronous Javascript

6th of June, 2015

Callbacks - Nested operations

function loadHero(loadingFinishedCallback) { http.get('/characters/hero.json', function (heroData) { http.get(heroData.modelUrl, function (model) {

loadingFinishedCallback({ data: heroData, model: model });

}); });}

Page 9: Steam Learn: Asynchronous Javascript

6th of June, 2015

Callbacks - Nested operations

function loadHero(loadingFinishedCallback) { http.get('/characters/hero.json', function (heroData) { http.get(heroData.modelUrl, function (model) { http.get(model.materialUrl, function (material) {

loadingFinishedCallback({ data: heroData, model: model, material: material });

}); }); });}

Page 10: Steam Learn: Asynchronous Javascript

6th of June, 2015

Callbacks - Nested operations

function loadHero(loadingFinishedCallback) { http.get('/characters/hero.json', function (heroData) { loadGraphics(heroData.modelUrl, function (graphics) {

loadingFinishedCallback({ data: heroData, model: graphics.model, material: graphics.material });

}); });}

Page 11: Steam Learn: Asynchronous Javascript

6th of June, 2015

Callbacks - Limits

● Nested callbacks are not handy

● Even worse with error catching

● Waiting for multiple callbacks is hard

Callbacks are bad for async operations

Page 12: Steam Learn: Asynchronous Javascript

6th of June, 2015

Table of contents

1. Callbacks

2. Promises

3. Generators

Page 13: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - Basics

function httpGet(url) { return new Promise(function (resolve) { http.get(url, function (data) { resolve(data); }); });}

Page 14: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - Basics

function httpGet(url) { return new Promise(function (resolve) { http.get(url, resolve); });}

Page 15: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - Basics

function httpGet(url) { return new Promise(function (resolve, reject) { http.get(url, resolve, reject); });}

Page 16: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - Chaining

function loadHero() { return httpGet('/characters/hero.json') .then(function (heroData) { return { data: heroData }; });}

loadHero().then(function (hero) { console.log(hero.data);});

Page 17: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - Chaining

function loadHero() { return httpGet('/characters/hero.json') .then(function (heroData) {

return httpGet(heroData.modelUrl).then(function (model) { return { data: heroData, model: model }; });

});}

loadHero().then(function (hero) { console.log(hero.data); console.log(hero.model);});

Page 18: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - Chaining

function loadHero() { var hero = {}; return httpGet('/characters/hero.json') .then(function (heroData) { hero.data = heroData; return httpGet(heroData.modelUrl); }) .then(function (model) { hero.model = model; return hero; });}

loadHero().then(function (hero) { console.log(hero.data); console.log(hero.model);});

Page 19: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - Chaining

function loadHero() { var hero = {}; return httpGet('/characters/hero.json') .then(function (heroData) { hero.data = heroData; return httpGet(heroData.modelUrl); }) .then(function (model) { hero.model = model; return httpGet(model.materialUrl); }) .then(function (material) { hero.material = material; return hero; });}

Page 20: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - Chaining

function loadHero() { var hero = {}; return httpGet('/characters/hero.json') .then(function (heroData) { hero.data = heroData; return httpGet(heroData.modelUrl); }) .then(function (model) { hero.model = model; return httpGet(model.materialUrl); }) .then(function (material) { hero.material = material; return hero; }) .catch(function (error) { console.log(error); return null; });

Page 21: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - Waiting all promises

function loadObjects() { return Promise.all([ loadHero(), loadEnemy(), loadDoor(), loadWall(), // ... ]);}

loadObjects().then(function (objects) { var hero = objects[0]; var enemy = objects[1]; // ...});

Page 22: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises - How to get them

● In Ecmascript 6 standard library

● Available through polyfills:https://github.com/jakearchibald/es6-promise

● Alternative APIs:https://github.com/kriskowal/qhttps://github.com/petkaantonov/bluebird

Page 23: Steam Learn: Asynchronous Javascript

6th of June, 2015

Promises

Nice, but…

● Verbose

● Still writing in an asynchronous way

We can do better!

Page 24: Steam Learn: Asynchronous Javascript

6th of June, 2015

Table of contents

1. Callbacks

2. Promises

3. Generators

Page 25: Steam Learn: Asynchronous Javascript

6th of June, 2015

Generator - Basics

function* counter() { for (var i = 0; i < 10; i++) { yield i; }}

var count = counter();console.log(count.next()); // 0console.log(count.next()); // 1// ...

Page 26: Steam Learn: Asynchronous Javascript

6th of June, 2015

Generator - Basics

function* loadHero(){ var hero = {};

hero.data = yield httpGet('/characters/hero.json'); hero.model = yield httpGet(hero.data.modelUrl); hero.material = yield httpGet(hero.model.materialUrl);

return hero;}

spawn(loadHero).then(function (hero) { console.log(hero); // { data: <...>, model: <...>, ... }});

Page 27: Steam Learn: Asynchronous Javascript

6th of June, 2015

Generator - Basics

function* loadHero(){ var hero = {};

try { hero.data = yield httpGet('/characters/hero.json'); hero.model = yield httpGet(hero.data.modelUrl); hero.material = yield httpGet(hero.model.materialUrl); } catch (error) { console.log(error); hero = null; }

return hero;}

spawn(loadHero).then(function (hero) { console.log(hero); // { data: <...>, model: <...>, ... }});

Page 28: Steam Learn: Asynchronous Javascript

6th of June, 2015

Generator - Basics

async function loadHero(){ var hero = {};

try { hero.data = await httpGet('/characters/hero.json'); hero.model = await httpGet(hero.data.modelUrl); hero.material = await httpGet(hero.model.materialUrl); } catch (error) { console.log(error); hero = null; }

return hero;}

loadHero().then(function () { console.log(hero); // { data: <...>, model: <...>, ... }});

Page 29: Steam Learn: Asynchronous Javascript

6th of June, 2015

Generator - Browser support

● Generator are ES6

● Async functions are ES7

● Use them today with transpilers:https://github.com/google/traceur-compilerhttps://babeljs.io/

Page 31: Steam Learn: Asynchronous Javascript

6th of June, 2015

Join the community !(in Paris)

Social networks :● Follow us on Twitter : https://twitter.com/steamlearn● Like us on Facebook : https://www.facebook.com/steamlearn

SteamLearn is an Inovia initiative : inovia.fr

You wish to be in the audience ? Join the meetup group! http://www.meetup.com/Steam-Learn/