Upload
maximilian-berghoff
View
856
Download
3
Embed Size (px)
Citation preview
REACTIVE JAVASCRIPT MIT RXJS - BASTA! 2016MAXIMILIAN BERGHOFF - 02.03.2016
Maximilian [email protected]/electrimaxxxMayflower GmbH - Wü[email protected]
REACTIVE EXTENSIONS -RX
HISTORYERIK MEIER
BRAIN BACKMANMATHEW PODWYSOCKI
LINQ TO EVENTS
VOLTA
WINDOWS FORMS<=>
WEB FORMS
BEISPIEL:
DRAG & DROPMAUSBEWEGUNG VERFOLGEN
EVENT LISTENER REGISTRIERENelem.addEventListener('mousedown', mousedown, false); elem.addEventListener('mouseup', mouseup, false); elem.addEventListener('mousemove', mousemove, false);
MOUSE DOWNfunction mousedown(e) isDown = true; state = startX: e.offsetX, startY: e.offsetY;
MOUSE MOVEfunction mousemove(e) if (!isDown) return; var delta = endX: e.clientX state.startX, endY: e.clientY state.startY ;
MOUSE UPfunction mouseup (e) isDown = false; state = null;
UNSUBSCRIBEfunction dispose() elem.removeEventListener('mousedown', mousedown, false); elem.removeEventListener('mouseup', mouseup, false); elem.removeEventListener('mousemove', mousemove, false);
DIE AKTEURE
ITERATOR PATTERN
var Iterator = function () ;
Iterator.prototype.next();
Iterator.prototype.rewind();
Iterator.prototype.current();
Iterator.prototype.hasNext();
TRAVERSIERENwhile (Iterator.hasNext()) console.log(Iterator.next());
GEDANKENSPIELListe von CocktailsEigenschaften: id, name, zutaten, prozent, ...Aufgabe: "id & name von allem Contails mit prozent > 5.0"
var cocktails = [ id: 100001, name: 'Piña Colada', zutaten: [], prozent: 5.0 , id: 100002, name: ' Tequila Sunrise', zutaten: [], prozent: 6.0 , id: 100003, name: ' Long Island', zutaten: [], prozent: 7.0 , ];
var newList = []; for(var i = 0; i <= cocktails.length; i++) if (cocktails[i].prozent > 5.0) newList.push(id: cocktails[i].id, title: cocktails[i].title)
console.log(newList);
var newList = []; cocktails.forEach(function (cocktail) if (cocktails[i].prozent > 5.0) newList.push(id: cocktail.id, title: cocktail.title) );
var godOnes = cocktails .filter(function (cocktail) return cocktail.prozent > 5; ) .map(function (cocktail) return id: cocktail.id, name: cocktail.name; );
OBSERVER PATTERN
Observable.prototype.subscribe()
Observer.prototype.notify()
var Observable = function () ;
Observable.prototype.subscribe = function () ;
Observable.prototype.unsubscribe = function () ;
var Observer = function () ;
Observer.prototype.notify = function() ;
WARUM?Entkopplungweniger prozedualer CodeErweiterbarkeit erhöht
DIE HOCHZEIT
By Ziko van Dijk (shot by myself) [ or ], GFDL CC BY-SA 3.0 via WikimediaCommons
REACTIVE EXTENSIONRxJavaRxJSRx.NetRx.ScalaRx.ClojureRx.Swift...
REACTIVEX.IO
GITHUB.COM/REACTIVE-EXTIONSION
STREAM VON EVENTS
var list = [1, 2, 3, 4, 5];
list.forEach(function (item) console.log("nexItem: %s", item); );
var list = [1, 2, 3, 4, 5];
var source = Rx.Observable.fromArray(list);
var disposal = source.subscribe( function (x) console.log('Next: ' + x);, function (err) console.log('Error: ' + err);, function () console.log('Completed'););
disposal.dispose();
OBSERVER
By Vince Alongi (Flickr) [ ], CC BY 2.0 via Wikimedia Commons
var disposal = source.subscribe( function (x) console.log('Next: ' + x);, function (err) console.log('Error: ' + err);, function () console.log('Completed'); );
function Observer()
Observer.prototype.onNext = function (value) ... ;
Observer.prototype.onError = function (error) ... ;
Observer.prototype.onCompleted = function () ... ;
var source = Rx.Observable.range(1,10);
var reducedSource = source.filter(function (value) return value % 2 === 0; );
var disposal1 = reducedSource.subscribe( function (x) console.log('Next 1: ' + x);, function (err) console.log('Error 1: ' + err);, function () console.log('Completed 1.'); );disposal1.dispose();
var disposal2 = source.subscribe( function (x) console.log('Next 2: ' + x);, function (err) console.log('Error 2: ' + err);, function () console.log('Completed 2'); );disposal2.dispose();
> Next 1: 2 > Next 1: 4 > Next 1: 6 > Next 1: 8 > Next 1: 10 > Completed 1. > Next 2: 1 > Next 2: 2 > Next 2: 3 > Next 2: 4 > Next 2: 5 > Next 2: 6 > Next 2: 7 > Next 2: 8 > Next 2: 9 > Next 2: 10 > Completed 2
OBSERVALBE
function Disposable()
Disposable.prototype.dispose = function () ...
function Observable()
/** * @return Disposable */Observable.prototype.subscribe = function (observer) ...
YOUTUBE
(ER-) ZEUGUNG
Rx.Observable.create()
var source = Rx.Observable.create(function (observer) observer.onNext(42); observer.onCompleted(); return function () console.log('disposed'); );
var subscription = source.subscribe( function (x) console.log('onNext: %s', x); , function (e) console.log('onError: %s', e); , function () console.log('onCompleted'); );
subscription.dispose();
> onNext: 42 > onCompleted > disposed
Rx.Observable.range()
var source = Rx.Observable.range(1, 5);
var subscription = source.subscribe( function (x) console.log('onNext: %s', x); , function (e) console.log('onError: %s', e); , function () console.log('onCompleted'); );
> onNext: 1 > onNext: 2 > onNext: 3 > onNext: 4 > onNext: 5
Rx.Observable.fromEvent(element, eventName, [selector]) // oderRx.Observable.fromCallback(func, [context], [selector])
var input = $('#input');
var source = Rx.Observable.fromEvent(input, 'keyup');
var subscription = source.subscribe( function (x) console.log('Next: key pressed!');, function (err) console.log('Error: %s', err);, function () console.log('Completed'););
var fs = require('fs'), Rx = require('rx');
var exists = Rx.Observable.fromCallback(fs.exists); var source = exists('file.txt');
var subscription = source.subscribe( function (x) console.log('Next: ' + x);, function (err) console.log('Error: ' + err);, function () console.log('Completed'); );
LINQLANGUAGE INTEGRATED QUERY
von Unbekannt [Public domain], via Wikimedia Commons
KOMBINATION.concat(); // oder.merge();
var sourceOne = Rx.Observable.range(1,5); var sourceTwo = Rx.Observable.range(6,5);
var merged = sourceOne.concat(sourceTwo); var disposal = merged.subscribe(function (x) console.log('Concat onNext: ' + x); );
OUTPUT> Concat onNext: 1 > Concat onNext: 2 > Concat onNext: 3 > Concat onNext: 4 > Concat onNext: 5 > Concat onNext: 6 > Concat onNext: 7 > Concat onNext: 8 > Concat onNext: 9 > Concat onNext: 10
var sourceOne = Rx.Observable.range(1,5); var sourceTwo = Rx.Observable.range(6,5);
var merged = sourceOne.merge(sourceTwo); var disposal = merged.subscribe(function (x) console.log('Merged onNext: ' + x); );
OUTPUT> Merged onNext: 1 > Merged onNext: 6 > Merged onNext: 2 > Merged onNext: 7 > Merged onNext: 3 > Merged onNext: 8 > Merged onNext: 4 > Merged onNext: 9 > Merged onNext: 5 > Merged onNext: 10
FILTER
var source = Rx.Observable.range(1,10);
var filtered = source.filter(function (x) return x % 2 === 0; );
var disposal = filtered.subscribe(function (x) console.log('onNext: ' + x); );
OUTPUT> onNext: 2 > onNext: 4 > onNext: 6 > onNext: 8 > onNext: 10
PROJEKTIONEN
var list = [ id: 100001, name: 'Piña Colada', zutaten: [], prozent: 5.0 , id: 100002, name: ' Tequila Sunrise', zutaten: [], prozent: 6.0 , id: 100003, name: ' Long Island', zutaten: [], prozent: 7.0 , ];
var source = Rx.Observable.from(list);
var ids = source.map(function (item) return item.id; );
var disposal = ids.subscribe(function (x) console.log('onNext Id: ' + x); );
disposal.dispose();
OUTPUTonNext Id: 100001 onNext Id: 100002 onNext Id: 100003
?.flatMap();
var source = Rx.Observable .range(1, 2) .flatMap(function (x) return Rx.Observable.range(x, 2); );
var subscription = source.subscribe( function (x) console.log('onNext: ' + x); );
return Rx.Observable.range(1, 2); return Rx.Observable.range(2, 2);
OUTPUT> onNext: 1 > onNext: 2 > onNext: 2 > onNext: 3
NOCH MEHR?GITHUB/DOKUMENTATION
PROMISES?Single ValueCancellation?
ARRAY OPERATORENVS.
RX OPERATOREN
ARRAY OPERATORENKomplette Liste wird durch gereichtdabei auf jedem Eintrag
Projektion - map, ..Gefiltert - reduce, filterErgänzt - concat, merge
RX OPERTORENJedes Event/Jeder Eintrag einzelndabei
Projektion - map, ..Gefiltert - reduce, filterErgänzt - concat, merge
Filter = STOP => nicht weiter gereichtErgänzung nur der Zugang für weiteren Stream
ACTION
von Thiemo Schuff (Eigenes Werk) [ ], CC BY-SA 3.0 via WikimediaCommons
<input type="text" id="input"/>
<h2>Results</h2> <ul id="results"> </ul>
var $input = $('#input'); var $results = $('#results');
var suggestions = Rx.Observable.fromEvent($input, 'keyup');
var suggestions = Rx.Observable.fromEvent($input, 'keyup') .pluck('target', 'value') .filter(function(text) return text.length > 2 ) .debounce(500 /* ms */) .distinctUntilChanged();
... flatMapLatest(function (term) return $.ajax( url: 'https://en.wikipedia.org/w/api.php', dataType: 'jsonp', data: action: 'opensearch', format: 'json', search: term ).promise(); );
... .subscribe( function(data) $results .empty() .append($.map(data[1], function (value) return $('<li>').text(value); )) , function(error) $results .empty() .append($('<li>')) .text('Error:' + error); );
JS FIDDLE
By Musik- och teatermuseet (Own work) [ ], CC BY-SA 3.0 via WikimediaCommons
QUESTIONS?Ask Now!Twitter: @ElectricMaxxxMail: [email protected]
LINKS, Slideshare folgtSlides in Markdown
RxJS docsMarblesListe an TutorialsRepositoryAusführliches TutorialVideo TutorialsBuch
ALTERNATIVEN
cyclejsBACONJS
< <
THANK YOU!
< <