in javascript - meetup · 2015-06-25 · user input ajax web sockets / sse web workers animations...
TRANSCRIPT
Functional Reactive Programming
in Javascript
what’s FRP?
let’s begin with
http://www.reactivemanifesto.org/
Responsive Message Driven
ResilientElastic
sweet dreams
so better start with
reactive paradigmvar b = 1, c = 1;
var a = b + c; // a == 2
b = 10;
● // a == ?● // imperative paradigm => a == 2● // reactive paradigm => a == 11
front end developmentis it synchronous or asynchronous?
● User Input● AJAX● Web Sockets / SSE● Web Workers● Animations● Cross origin frame communication● Updating the DOM
we deal with
● User Input● AJAX● Web Sockets / SSE● Web Workers● Animations● Cross origin frame communication● Updating the DOM
most are async!
tools we use
callbacks
var el = document.getElementById("my-button");
el.addEventListener("click", function () {
console.log(‘my button was clicked’);
});
promises$http(endpoint1)
.get({q: ‘frp’})
.then(function (data) {
console.log(‘We got data back from ajax %s’, data);
})
.then(function (data) {
return $http(endpoint2).get({id: data.id});
})
generators in ES7
async(function main() {
var result1 = await request( "http://endpoint.1" );
var data = JSON.parse( result1 );
var result2 = await request( "http://endpoint.2?id=" + data.id );
var resp = JSON.parse( result2 );
console.log( "Value: " + resp.value );
})
problems● callback hell● try / catch (except for generators)● memory leaks● reduced composability
event driven programmingwe react to events
is reason about event streams
what we’re really trying to do
any number of valuesArray
over any amount of timef(time) / async
an event stream would be
first class citizen of FRP
observable
ObserverIterator
Gang of Four - Design Patterns
ES6 EventEmitter
array VS event
array === collection
events === collection
collections are iterable
observable === collection + time
observable API
var subscription = myObservable.subscribe(function (val) {
console.log(‘Next: %s’, val);
});
from the EventEmitter?
so… how is that different
we know when it’s donevar subscription = myObservable.subscribe(
onNext,
onError,
onCompleted
);
like promises
we got set operators● map● flatMap● reduce● merge● concat● zip
more operators● debounce● buffer● skipUntil● flatMapLatest● combineLatest● switch● retry
observables can model● mouse clicks● key presses● scrolling● animations● AJAX Polling, Web Sockets● timers● even… constants
operatorshttp://rxmarbles.com/
filter
debounce
distinctUntilChanged
takeUntil
exampleplease!
mousedown.flatMap((md) => {
var startX = md.offsetX, startY = md.offsetY;
return mousemove.map((mm) => {
return {
left: mm.clientX - startX,
top: mm.clientY - startY
};
}).takeUntil(mouseup);
}).subscribe((pos) => {
dragTarget.style.top = pos.top + 'px';
dragTarget.style.left = pos.left + 'px';
});
drag & drop
Autocompleteyes I know, the classic example
requirements● filter queries● throttle requests● retry (overcome network glitches)● avoid duplicate requests● match results to latest query● abort no longer valid requests
keyup => resultsvar keyPress = $('#search').keyupAsObservable();
.keyPress.map((ev) => { return ev.target.value; })
.filter((text) => { return text.length > 3; })
.debounce(500)
.distinctUntilChanged()
.flatMapLatest(search.retry(3).takeUntil(keyPress))
.map((d) => { return d.response[1]; })
.subscribe(showResults, showError);
throttling
no duplicate requests
filtering
match/abort
response/results
gets even better
things we can do
● cancel (can’t do with Promises)● be lazy until a subscriber subscribes (cold)● setup datasource on first subscription● teardown datasource on disposal
not convinced yet?
observable future● TC39 proposal to add to ES7
○ https://github.com/zenparsing/es-observable
● Angular 2 first class support● ReactJS first class support
http://victorsavkin.com/post/108837493941/better-support-for-functional-programming-in
Rx in production
still...● steep learning curve● old habits die hard● tricky to work with classic MV*● poor/difficult documentation (is getting better)
libraries
● Rx.js (port of Reactive Extensions to JS)● Bacon.js● Kefir (faster bacon :)
origins
Microsoft Research
● A Brief Introduction to ActiveVRML - Conan Elliott● Functional Reactive Animations - Conan Elliott & Paul
Hudak
resources● Fran Tutorial - http://conal.net/fran/tutorial.htm● Simply Reactive - http://conal.net/papers/simply-reactive/● Reactive Extensions - https://github.com/Reactive-Extensions/RxJS● BaconJS - https://baconjs.github.io/● Async JavaScript with Reactive Extensions (Jafar Husain)
○ https://www.youtube.com/watch?v=XRYN2xt11Ek● RxJS at Modern Web UI (Ben Lesh)
○ https://www.youtube.com/watch?v=yk_6eU3Hcwo● http://www.slideshare.net/stefanmayer13/functional-reactive-programming-with-rxjs● https://gist.github.com/staltz/868e7e9bc2a7b8c1f754● RxJSKoans - https://rxkoans.codeplex.com/● RxMarbles - http://rxmarbles.com/● Reactive programming and MVC (Aaron Stacy)
○ http://aaronstacy.com/writings/reactive-programming-and-mvc/
Questions?