cycle.js - functional reactive ui framework (nikos kalogridis)

40
CYCLE.JS A Functional reactive UI framework Nikos Kalogridis @nikoskalogridis

Upload: greecejs

Post on 22-Jan-2018

128 views

Category:

Technology


3 download

TRANSCRIPT

CYCLE.JSA Functional reactive UI framework

Nikos Kalogridis@nikoskalogridis

WHY ANOTHER FRAMEWORK?Programming is hard!Complexity of Web apps is growing exponentiallyAsynchronous programming complicates thingseven more

CYCLE.JS

ANDRÉ MEDEIROS (AKA. ANDRÉ STALTZ)

CYCLE.JS FEATURESFunctionalReactiveUnidirectonal flow of dataVirtual DOMA Cycle.js program is a pure function - no sideeffects

CYCLE.JS HISTORYNov-2014 - Initial commit on github based on RxJsNov-2015 - A fork of the project was made basedmost.jsJun-2016 - Merged back this time supportingxstream, Rxjs v4, Rxjs v5 and most.jsTC39 Observable proposalFeb-2017 - Dropped stream adapters and now usesObservable to convert between streams. Alsodropped support for Rxjs v4

FUNCTIONAL PROGRAMMINGDeclarative instead of imperativePure functionsImmutability

MAP

Returns a new array with the result of applying afunction on each element of the array

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

myArray.map(function (value) { return value + 1; });

// -> [2, 3, 4, 5, 6]

FILTER

Returns a new array with all elements that pass thetest implemented by the provided function

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

myArray.filter(function (value) { return value < 4; });

// -> [1, 2, 3]

REDUCE

Reduces the elements to a single value applying afunction to each of them

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

myArray.reduce(function (acc, value) { return acc + value; }, 0);

// -> 15

IMPERATIVE VS DECLARATIVEGiven an array of numbers return the numbers that

are less than 4 and add to each of those 10var myArray = [1, 2, 3, 4, 5]; var result = []; var i = 0;

for (i; i < myArray.length; i += 1) { if (myArray[i] < 4) { result.push(myArray[i] + 10); } }

var myArray = [1, 2, 3, 4, 5]; var result = myArray .filter((value) => value < 4) .map((value) => value + 10);

HIGHER ORDER FUNCTIONa function that takes a function as a parameteror returns a functionor both

HIGHER ORDER FUNCTIONEXAMPLES

function add(amount) { return function (value) { return value + amount; } }

function lessThan(amount) { return function (value) { return value < amount; } }

var result = myArray.filter(lessThan(4)).map(add(10));

PURE FUNCTIONits return value is affected only by its passedparametersand has no side effects

PURE VS IMPUREvar a = 10;

function impure(x) { return x + a;}

function pure(x, y) { return x + y;}

SIDE EFFECTSvar a = 0;

function impure(x) { a = x + a; }

function impure(x) { console.log(x); return x + 1; }

ASYNCHRONOUSPROGRAMMING IN JAVASCRIPT

CallbacksPromisesGenerators / yieldAsync / awaitObservables

CALLBACKSvar counter = 0;

function callback() { counter += 1;}

document .getElementById('myButton') .addEventListener('click', callback);

var xhr = new XMLHttpRequest(); xhr.open('GET', '/server', true);

xhr.onload = function () { // Request finished. Do processing here. };

PROMISESvar requestPromise = fetch({url: 'http://www.google.com'});

requestPromise .then(function (response) { // do something with the response }) .catch(function (error) { // handle the error });

GENERATORS / YIELDfunction* foo () { var index = 0; while (index < 2) { yield index++; } } var bar = foo();

console.log(bar.next()); // { value: 0, done: false } console.log(bar.next()); // { value: 1, done: false } console.log(bar.next()); // { value: undefined, done: true }

ASYNC / AWAITasync function save(Something) { try { await Something.save(); } catch (ex) { //error handling } console.log('success');}

OBSERVABLE// data$ is an Observable object var subscription = data$.subscribe( { next: function (value) { // handle next value }, error: function (error) { // handle error }, complete: function () { // finished so do cleanup... } } );

REACTIVE PROGRAMMINGis programming with data streams (synchronous orasynchronous)on top of that you are given an amazing toolbox offunctions to combine, create, filter any of thosestreams

REACTIVE LIBRARIES INJAVASCRIPT

Bacon.jsRxjskefir.jsmost.jsxstream

RXJS EXAMPLEimport Rx from 'rxjs/Rx';

let counter = 0;

const increaseButton = document.querySelector('#increase'); const increaseClick$ = Rx.Observable.fromEvent(increaseButton, 'click');

increaseClick$.subscribe({ next: function () { // click received counter += 1; console.log(counter); } });

RXJS EXAMPLE REVISEDimport Rx from 'rxjs/Rx'; const increaseButton = document.querySelector('#increase'); const increaseClick$ = Rx.Observable.fromEvent(increaseButton, 'click'); const counter$ = increaseClick$ .mapTo(1) // always maps to a constant value .scan((acc, value) => acc + value, 0); // hint: reduce

counter$.subscribe({ next: function (counter) { // new count event received console.log(counter); } });

OTHER TYPES OF STREAMSRx.Observable.from([1, 2, 3, 4, 5]) .filter((x) => x < 4) .map((x) => x + 10) .subscribe({ next: (value) => console.log(value), complete: () => console.log('done') });

// ->// 11// 12// 13// done

PROMISE AS A STREAMconst myPromise = new Promise((resolve) => resolve('hello')); Rx.Observable.from(myPromise) .subscribe({ next: (value) => console.log(value), complete: () => console.log('done') });

// ->// hello // done

COMBINING STREAMSconst data1$ = Rx.Observable.from([1, 2, 3]);const data2$ = Rx.Observable.from([6, 7, 8]);Rx.merge(data1$, data2$) .subscribe({ next: (value) => console.log(value) });// ->// 1 // 6 // 2 // 7 // 3 // 8

MERGE OPERATOR

CYCLE.JS MODEL

Human

Senses Actuators

InputOutput

Computer

A CYCLE.JS PROGRAM IS APURE FUNCTION

function cycleProgram(sources) { return sinks;}

function main(sources) { const model$ = sources .DOM.select('.increase').events('click') .mapTo(1).fold((acc, value) => acc + value, 0);

const vtree$ = model$.map((value) => div([ button('.increase', 'Increase'), span(value) ]) );

return {DOM: vtree$}; }

Cycle.run(main, { DOM: makeDOMDriver('#app') });

NO SIDE EFFECTS

SourcesSinks

main()

DOM side effects

HTTP side effects

Other side effects

pure dataflow

IN CYCLE.JS

DEMO

PROSTruly reactive programming styleDeclarative UI designFast - thanks to Snabdom and xstreamFractal state management

CONSBrain rewiring for using functional reactive styleRelatively small community compared to React orAngularSteep learning curve especially on stream librariesLacks a complete UI component library (as of today)

USEFUL LINKShttps://cycle.js.org/http://widdersh.in/tricycle/https://github.com/cyclejs-communityhttps://gitter.im/cyclejs/cyclejshttps://github.com/staltz/cycle-onionifyhttps://github.com/cyclejs-community/cyclic-routerhttp://staltz.com

QUESTIONS

THANK YOU