Upload
stefanmayer13
View
2.465
Download
5
Embed Size (px)
DESCRIPTION
Talk by @mzupzup and @stefanmayer13 about Functional Reactive Programming in JavaScript at the 4th grazjs meetup (http://www.meetup.com/grazjs/).
Citation preview
Functional Reactive
Programming in JS
Mario Zupan@mzupzup
Stefan Mayer@stefanmayer13
Who are we?
@stefanmayer13 @mzupzup
2
Motivation
■ Technology stack re-evaluation
■ Lessons learned
■ Functional Programming
■ QCon NYC
[1]
3
What is Functional Reactive
Programming?
4
Reactive Manifesto
[2]
5
Reactive Manifesto
? ?
? ? [2]
6
Functional Programming
■ Evaluation of mathematical functions
■ Avoid mutable state
■ Referential transparency
■ Avoid side-effects
■ Reusable functions over reusable object
■ Function composition over object
composition
[1]
7
Functional Programming
■ map
■ filter
■ mergeAll
■ reduce
■ zip
[3]
[4] 8
var data = [1, 2, 3, 4, 5];
var numbers = data.map(function (nr) {
return nr + 1;
});
// numbers = [2, 3, 4, 5, 6]
9
var data = [1, 2, 3, 4, 5, 6, 7];
var numbers = data.filter(function (nr) {
return nr % 2 === 0;
});
// numbers = [2, 4, 6]
10
var data = [1, 2, 3, 4, 5, 6, 7];
var numbers = data.map(function (nr) {
return nr + 1;
}).filter(function (nr) {
return nr % 2 === 0;
});
// numbers = [2, 4, 6, 8]11
var data = [[1, 2], [3, 4], 5, [6], 7, 8];
var numbers = data.mergeAll();
// numbers = [1, 2, 3, 4, 5, 6, 7, 8]
12
var data = [{
numbers: [1, 2]
}, {
numbers: [3, 4]
}];
var numbersFlatMap = data.flatMap(function (object) {
return object.numbers;
});
// numbersMap = [[1, 2], [3, 4]]
// numbersFlatMap = [1, 2, 3, 4]
13
var data = [1, 2, 3, 4];
var sum = data.reduce(function(acc, value) {
return acc + value;
});
// sum = 10
14
var data = [5, 7, 3, 4];
var min = data.reduce(function(acc, value) {
return acc < value ? acc : value;
});
// min = 3
15
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
var array = Array.zip(array1, array2,
function(left, right) {
return [left, right];
});
// array = [[1, 4], [2, 5], [3, 6]]16
Reactive Programming
■ Asynchronous data streams
■ Everything is a stream
● click events
● user inputs
● data from a server
■ streams rock!
17
Reactive Programming
[5]18
F + R + P
■ Powerful composition and aggregation of
streams
■ Good fit for concurrent and event-driven
systems
■ Declarative
■ Easy to test
[6]19
Observables
■ Stream of data over time
■ Hot vs cold observables
■ Asynchronous
■ Lazy
■ queryable, bufferable, pausable…
■ more than 120 operations
[7]
20
Observable Creation
Rx.Observable.fromArray([1, 2, 3]);
Rx.Observable.fromEvent(input, 'click');
Rx.Observable.fromEvent(eventEmitter, 'data', fn);
Rx.Observable.fromCallback(fs.exists);
Rx.Observable.fromNodeCallback(fs.exists);
Rx.Observable.fromPromise(somePromise);
Rx.Observable.fromIterable(function*() {yield 20});21
var range = Rx.Observable.range(1, 3); // 1, 2, 3
var range = range.subscribe(function(value) {},function(error) {},function() {}
);
Observable Basics
optional
22
var range = Rx.Observable.range(1, 10) // 1, 2, 3 ...
.filter(function(value) { return value % 2 === 0; })
.map(function(value) { return "<span>" + value + "</span>"; })
.takeLast(1);
var subscription = range.subscribe(
function(value) { console.log("last even value: " + value); });
// "last even value: <span>10</span>"
Observable Basics
23
Cold Observables
[8]
24
Hot Observables
[9]
25
Autocomplete
● Multiple requests
● Async results
● Race conditions
● State
● ...
[10]
26
Autocomplete 1/2
var keyup = Rx.Observable.fromEvent(input, 'keyup')
.map(function (e) {
return e.target.value; // map to text
})
.filter(function (input) {
return input.length > 2; // filter relevant values
})
.debounce(250)
27
.distinctUntilChanged() // only if changes
.flatMapLatest(doAsyncSearch() // do async search on server
.retry(3))
.takeUntil(cancelStream) // cancel stream
.subscribe(
function (data) { // do UI stuff },
function (error) { // do error handling }
);
Autocomplete 2/2
28
Drag & Drop 1/2
var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown');
var mousemove = Rx.Observable.fromEvent(document, 'mousemove');
var mouseup = Rx.Observable.fromEvent(dragTarget, 'mouseup');
[11]
29
mousedown.flatMap(function (md) {
// get starting coordinates
var startX = md.offsetX, startY = md.offsetY;
return mousemove.map(function (mm) {
// return the mouse distance from start
return {left: mm.clientX - startX, top: mm.clientY - startY };
}).takeUntil(mouseup);
}).subscribe(function (pos) {
// do UI stuff
}); [11]
30
Some Cool Stuff on Observables
.bufferWithTime(500)
.pausable(pauser), .pausableBuffered(..)
.repeat(3)
.skip(1), skipUntilWithTime(..)
.do() // for side-effects like logging
.onErrorResumeNext(second) // resume with other obs
.window() // project into windows
.timestamp() // add time for each value
.delay() 31
RxJS
Supported
■ IE6+
■ Chrome 4+
■ FireFox 1+
■ Node.js v0.4+
Size (minified & gzipped):
■ all - 23,1k
■ lite - 13,5k
■ compat - 12,5k
■ ES5 core - 12k
[12]
32
Framework Bridges
■ AngularJS
■ ReactJS
■ jQuery
■ ExtJS
■ NodeJS
■ Backbone
■ ...
33
Companies using Rx in Production
[13]
34
Alternatives to RxJS
■ BaconJS
■ Kefir
■ (Elm)
35
Conclusion
■ There is a learning curve
■ Great abstraction for async & events
■ Improves
● Readability
● Reusability
● Scalability
■ Both on the front- and backend
36
Learning RxJS
■ RxKoans
○ https://github.com/Reactive-Extensions/RxJSKoans
■ learnRx
○ https://github.com/jhusain/learnrx
■ The Introduction to Reactive Programming you've been
missing
○ https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
■ rxMarbles
○ http://rxmarbles.com/
37
Image references■ 1 - http://www.ylies.fr/
■ 2 - http://www.reactivemanifesto.org
■ 3 - http://reactivex.io/
■ 4 - https://raw.githubusercontent.com/wiki/ReactiveX/RxJava/
■ 5 - http://buildstuff14.sched.org/event/9ead0e99b3c1c0edddec6c7c8d526125#.VHEgq5PF-kQ
■ 6 - http://www.cclscorp.com
■ 7 - http://www.pharmmd.com/
■ 8 - http://blogs.msdn.com/
■ 9 - http://blogs.msdn.com/
■ 10 - https://www.google.at
■ 11 - http://dockphp.com/
■ 12 - http://www.thechrisyates.com/
■ 13 - http://www.reactivex.io
■ 14 - http://www.quickmeme.com/
38
Thank you
@stefanmayer13
@mzupzup
[14]
39