in javascript - meetupfiles.meetup.com/18631212/functional-reactive-programming.pdf · user input...

56
Functional Reactive Programming in Javascript

Upload: doanngoc

Post on 30-Jul-2018

222 views

Category:

Documents


0 download

TRANSCRIPT

Functional Reactive Programming

in Javascript

whoami

Stratos PavlakisWorkable UI Tech Lead

[email protected]

th3hunt

FRP newbie!

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?