25
Bacon.js How to handle JS streams Rodolphe Belouin @rbelouin Human Talks, Nantes, 2015-01-13

Bacon.js — Gérer efficacement les flux de données en Javascript

Embed Size (px)

Citation preview

Page 1: Bacon.js — Gérer efficacement les flux de données en Javascript

Bacon.jsHow to handle JS streams

Rodolphe Belouin @rbelouinHuman Talks, Nantes, 2015-01-13

Page 2: Bacon.js — Gérer efficacement les flux de données en Javascript

What do I do?

I work at Clever-Cloud and my job is to make developers happy.

Page 3: Bacon.js — Gérer efficacement les flux de données en Javascript

The Clever-Cloud dashboard

Page 4: Bacon.js — Gérer efficacement les flux de données en Javascript

We are doing lots of stuff, client-side

Page 5: Bacon.js — Gérer efficacement les flux de données en Javascript

Example: the critical action button

Launch a rocket

Page 6: Bacon.js — Gérer efficacement les flux de données en Javascript

Launch a rocket

Abort (5s,4s,3s…)

Rocket launched!

click

HTTP request

Launch a rocket (…)

click

Page 7: Bacon.js — Gérer efficacement les flux de données en Javascript

var intervalId;

function startCountdown(onend) { var duration = 10; updateTheCountdownButton(duration);

intervalId = setInterval(function() {duration--;updateTheCountdownButton(duration);

if(duration == 0) { onend();

} }, 1000);}

The naive countdown

Page 8: Bacon.js — Gérer efficacement les flux de données en Javascript

You get spaghetti code

Page 9: Bacon.js — Gérer efficacement les flux de données en Javascript

var $performButton = document.querySelector("#critical-action");var $abortButton = document.querySelector("#abort-action");

$performButton.addEventListener("click", function() { startCountdown(function onend() { sendRequest(function(result) { /* The critical action is done */

}); });});

$abortButton.addEventListener(“click”, function() { /* Do some stuff to abort the critical action */});

A lot of asynchronous work

Page 10: Bacon.js — Gérer efficacement les flux de données en Javascript
Page 11: Bacon.js — Gérer efficacement les flux de données en Javascript

We need modularity and composition

Page 12: Bacon.js — Gérer efficacement les flux de données en Javascript

Here comes Bacon.js

Page 13: Bacon.js — Gérer efficacement les flux de données en Javascript

Click streams

var s_performClick = $(“button#perform-button”).asEventStream(“click”);

var s_abortClick = $(“button#abort-button”).asEventStream(“click”);

E E E

Page 14: Bacon.js — Gérer efficacement les flux de données en Javascript

Abort action streamvar s_abortAction = s_performClick.flatMapLatest(function() { return s_abortClick;});

E

s_performClick

E

s_abortAction

E

s_abortClickE E

Waiting for a click

Page 15: Bacon.js — Gérer efficacement les flux de données en Javascript

The final countdown streamvar s_countdown = s_performed.flatMapLatest(function() { var d = 10; var s_seconds = Bacon.interval(1000, 1); var s_remainingSeconds = s_seconds.scan(d, function(rem, sec) { return rem - sec; }); return s_remainingSeconds

.takeUntil(s_abortClick)

.takeWhile(function(countdown) { return countdown >= 0;

});});

Page 16: Bacon.js — Gérer efficacement les flux de données en Javascript

The final countdown stream1

s_seconds1 11 1 111

s_abortClickE

s_remainingSeconds10 9 8 7 6 5 4 3

s_countdown10 9 8 7

Page 17: Bacon.js — Gérer efficacement les flux de données en Javascript

Enjoy the stream POWAA!

Page 18: Bacon.js — Gérer efficacement les flux de données en Javascript

HTTP requests streamsvar s_notAborted = s_countdown.filter(function(countdown) { return countdown == 0;}).take(1);

var s_performed = s_notAborted.flatMapLatest(function() { return Bacon.fromPromise($.post(“/critical”));});

E

s_notAborted

R

s_performed

HTTP request

Page 19: Bacon.js — Gérer efficacement les flux de données en Javascript

Stop working on actions, and transform values

Page 20: Bacon.js — Gérer efficacement les flux de données en Javascript

Hide or display buttons

s_performClick.onValue(function() { $performButton.hide(); $abortButton.show();});

s_abortClick.onValue(function() { $abortButton.hide(); $performButton.show();});

Page 21: Bacon.js — Gérer efficacement les flux de données en Javascript

Display the countdown

s_countdown .map(function(seconds) { return "Abort (" + seconds + "s)"; }) .assign($abortButton, "text");

Page 22: Bacon.js — Gérer efficacement les flux de données en Javascript

Display a loader during a request

var s_loading = s_notAborted.awaiting(s_performed);s_loading.onValue(handleLoader($performButton));

s_notAbortedE

s_performedE

s_loadingfalse true false

HTTP request

Page 23: Bacon.js — Gérer efficacement les flux de données en Javascript

Display a message when all is overs_notAborted.map(true).toProperty(false) .assign($abortButton, "attr", "disabled");

s_notAborted.map("The action has been done") .assign($abortButton, "text");

Page 24: Bacon.js — Gérer efficacement les flux de données en Javascript

May the streams be with you

Page 25: Bacon.js — Gérer efficacement les flux de données en Javascript

Questions?http://baconjs.github.io

https://github.com/baconjs/bacon.js

You can train online: http://learn-bacon.herokuapp.com/

I am Rodolphe Belouin. @rbelouin on Twitter & Github