Functional Reactive Programming in Javascript



by
Thomas Gorny
 

Das Problem

  • Komplexe,
    asynchrone
    Webanwendungen

  • Callback  Hell  
(function($) {
$(function(){
$("button").click(function(e) {
$.get("/test.json", function(data, textStatus, jqXHR) {
$(".list").each(function() {
$(this).click(function(e) {
setTimeout(function() {
alert("Hello World!");
}, 1000);
});
});
});
});
});
})(jQuery);

 

Callbacks Sind böse!

 Nur Seiten-Effekte!
  • Synchronisierung
  • Control Flow
  • Error Handling

lösung:


REACTIVE

Functional

Event-Streams

Reactive



A = B + C
B = D + E


REACTIVE


A  =  B  +  C

B  =  D  +  E



E  ändert sich

⇒  B  neu berechnet

⇒  A  neu berechnet

Reactive



Data-Binding

Variablen wie Zellen
in Excel-Tabellen

Functional


Pure  Functions


f :  A  →  B

Functional


monaden


Behälter für beliebigen Inhalt

FUNCTIONAL

M sind First Class Values M  sind Parameter
M sind Return-Werte

Functional


M.map( f )

Functional


You know Monads!

Array (sequenziell)

FUNCTIONAL


YOU KNOW MONADS!

Promise (asynchron)

EVEnt StrEAms


Container 
für  sequenzielle,
asynchrone Werte
Veränderung über die Zeit

Event Streams


stream.map()

EVENT STREAMs

stream.map()
stream.reduce()
stream.filter()
stream.merge()
stream.takeUntil()
stream.flatMap()
...
array.map()
array.reduce()
array.filter()
array.concat()

Event Streams

sind reaktive,
funktionale
Datenstrukturen

Event Streams


Libraries

RxJS

Bacon.js
 

Achtung :  20 sek  Code !
   
 
    function xyFromEvent(v){ 
        return {x: v.clientX, y: v.clientY} 
    }

    function getDelta(t){
        var a = t[1];
        var b = t[0];
        return {x: a.x-b.x, y: a.y-b.y}; 
    }

    function add(p1, p2) {
        return {x: p1.x + p2.x, y: p1.y + p2.y};   
    }
    
    var startDrag = block.asEventStream('mousedown')
    var endDrag = block.asEventStream('mouseup')
            
    var draggingDeltas = startDrag.flatMap(function() {
        return html.asEventStream('mousemove')
            .map(xyFromEvent)
            .slidingWindow(2,2)
            .map(getDelta)
            .takeUntil(endDrag)
    })
    
    var blockPosition = draggingDeltas.scan({x: 0, y: 0}, add);
    
    blockPosition.onValue(function(pos) {
        block.css({
            top  : pos.y + "px",
            left : pos.x + "px"
        });
    });
    





Danke   : )

Functional Reactive Programming in JavaScript

By Thomas Gorny

Functional Reactive Programming in JavaScript

  • 2,098