functional reactive programming in javascript

39
Functional Reactive Programming in JS Mario Zupan @mzupzup Stefan Mayer @stefanmayer13

Upload: zupzuporg

Post on 12-Apr-2017

47 views

Category:

Software


1 download

TRANSCRIPT

Functional Reactive Programming in JS

Mario Zupan@mzupzup

Stefan Mayer@stefanmayer13

Who are we?@stefanmayer13 @mzupzup

Motivation

■ Technology stack re-evaluation■ Lessons learned■ Functional Programming■ QCon NYC

What is Functional Reactive Programming?

Reactive Manifesto

Reactive Manifesto

? ?

? ?

Functional Programming■ Evaluation of mathematical functions■ Avoid mutable state■ Referential transparency■ Avoid side-effects■ Reusable functions over reusable object■ Function composition over object

composition

Functional Programming

■ map■ filter■ mergeAll■ reduce■ zip

var data = [1, 2, 3, 4, 5];

var numbers = data.map(function (nr) {

return nr + 1;

});

//numbers = [2, 3, 4, 5, 6]

var data = [1, 2, 3, 4, 5, 6, 7];

var numbers = data.filter(function (nr) {

return nr % 2 === 0;

});

// numbers = [2, 4, 6]

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]

var data = [[1, 2], [3, 4], 5, [6], 7, 8];

var numbers = data.mergeAll();

// numbers = [1, 2, 3, 4, 5, 6, 7, 8]

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]

var data = [1, 2, 3, 4];

var sum = data.reduce(function(acc, value) {

return acc + value;

});

// sum = 10

var data = [5, 7, 3, 4];

var min = data.reduce(function(acc, value) {

return acc < value ? acc : value;

});

// min = 3

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]]

Reactive Programming

■ Asynchronous data streams■ Everything is a stream

● click events● user inputs● data from a server

■ streams rock!

Reactive Programming

F + R + P

■ Powerful Composition and Aggregation of streams

■ Good fit for concurrent and event-driven systems

■ Declarative■ Easy to test

Observables

■ Stream of data over time■ Hot vs Cold Observables■ Asynchronous■ Lazy■ queryable, bufferable, pausable…■ more than 120 operations

Observable CreationRx.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});

var range = Rx.Observable.range(1, 3); // 1, 2, 3

var range = range.subscribe(

function(value) {},

function(error) {},

function() {}

);

Observable Basics

optional

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

Cold Observables

Hot Observables

Autocomplete

● Multiple requests

● Async results

● Race conditions

● State

● ...

Autocomplete 1/2var 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)

.distinctUntilChanged() // only if changes

.flatMapLatest(doAsyncSearch() // do async search on server

.retry(3))

.takeUntil(cancelStream) // chancel stream

.subscribe(

function (data) { // do UI stuff },

function (error) { // do error handling }

);

Autocomplete 2/2

Drag & Drop 1/2var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown');

var mousemove = Rx.Observable.fromEvent(document, 'mousemove');

var mouseup = Rx.Observable.fromEvent(dragTarget, 'mouseup');

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

});

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()

RxJSSupported

■ IE6+■ Chrome 4+■ FireFox 1+■ Node.js v0.4+

Size (minified & gzipped):■ all - 23,1k■ lite - 13,5k■ compat - 12,5k■ ES5 core - 12k

Framework Bridges

■ AngularJS■ ReactJS■ jQuery■ ExtJS■ NodeJS■ Backbone■ ...

Companies using Rx in Production

Alternatives to RxJS

■ BaconJS■ Kefir■ (Elm)

Conclusion

■ There is a learning curve■ Great abstraction for async & events ■ Improves

● Readability● Reusability● Scalability

■ Both on the front- and backend

Image references■ KefirJS - https://camo.githubusercontent.com/■ BaconJS - http://baconjs.github.io■ data stream - http://www.pharmmd.com/■ Elm - http://elm-lang.org■ Browsers - http://www.thechrisyates.com/■ websocket logo - http://blog.appharbor.com/■ drag n drop - http://dockphp.com/■ f(x) - http://www.ylies.fr/■ qcon - https://qconsf.com/■ check sign - http://www.cclscorp.com ■ map - http://reactivex.io/■ reactivex logo - http://reactivex.io■ chuck norris - http://www.quickmeme.com/ ■ sencha - http://www.sencha.com/■ reactive companies - http://www.reactivex.io ■ filter reactive - https://raw.githubusercontent.com/wiki/ReactiveX/RxJava/■ node logo - http://calebmadrigal.com/■ extjs - http://marceloagustini.files.wordpress.com/■ hot observables - http://blogs.msdn.com/■ cold observables - http://blogs.msdn.com/ ■ backbone - http://2.bp.blogspot.com/■ reactjs - http://moduscreate.com/■ angular - http://www.w3schools.com/■ reactive diagram observables - http://buildstuff14.sched.org/event/9ead0e99b3c1c0edddec6c7c8d526125#.VHEgq5PF-kQ ■ reactivemanifesto - http://www.reactivemanifesto.org

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/

Thank you

@stefanmayer13@mzupzup