Skip to content

Instantly share code, notes, and snippets.

@MikeBild
Created September 27, 2013 06:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MikeBild/6725003 to your computer and use it in GitHub Desktop.
Save MikeBild/6725003 to your computer and use it in GitHub Desktop.
reactive applications - some examples
<!DOCTYPE HTML>
<html>
<head>
<title>Reactive Applications</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.1.11/rx.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.1.11/rx.aggregates.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.1.18/rx.time.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.1.11/rx.binding.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/2.0.7/rx.dom.min.js"></script>
</head>
<body>
<ul id="sections">
<li>EventDriven</li>
<li>Scalable</li>
<li>Resilient</li>
<li>Interactive</li>
</ul>
<section id="EventDriven" style="display: none">
<span>Event-Driven</span>
<div>
<div>Product Price: 8.0</div>
<div>Number: <span id="displayNumber">0</span></div>
<div>Amount: <span id="displayAmount">0.0</span></dov>
<button id="more">more</button>
<button id="less">less</button>
</div>
</section>
<section id="Scalable" style="display: none">
<span>Scalable</span>
<div>
<ul id="displayScalable"></ul>
</div>
</section>
<section id="Resilient" style="display: none">
<span>Resilient</span>
<div>
<ul id="displayResilient"></ul>
</div>
</section>
<section id="Interactive" style="display: none">
<span>Interactive</span>
<div>
<input type="text" id="textInput">
<ul id="results"></ul>
</div>
</section>
<script>
var Basics = function() {
var _eventdriven = function(){
var Dal = function(){
var _self = this;
var _events = [];
var _load = function(){
return Rx.Observable.fromArray(_events);
};
var _save = function(event){
_events.push(event);
};
return {
load : _load,
save: _save
}
};
var Logic = function(){
var _calculatePrice = function(stream, price){
return stream
.map(function(x){
return x.Type === "added" ? 1 : -1;
})
.aggregate(function(acc, x) {
return acc + x;
})
.map(function(next){
return new Cart(price, next, next * price);
});
};
return {
calculatePrice: _calculatePrice
};
};
var Cart = function(price, count, amount){
return {
Count: count || 0,
Amount: amount || 0.0
}
};
var Action = function(type){
return {
Type: type || "",
}
};
var View = function() {
var _displayAmount = function(value){
document.getElementById('displayAmount').innerText = value;
};
var _displayNumber = function(value){
document.getElementById('displayNumber').innerText = value;
};
var _onMore = function(){
return Rx.DOM.fromEvent(document.getElementById('more'), 'click');
};
var _onLess = function(){
return Rx.DOM.fromEvent(document.getElementById('less'), 'click');
}
return {
displayNumber: _displayNumber,
displayAmount: _displayAmount,
onMore: _onMore,
onLess: _onLess
};
};
var view = new View();
var logic = new Logic();
var dal = new Dal();
var moreStream = view.onMore()
.doAction(function(next){
dal.save(new Action("added"));
});
var lessStream = view.onLess()
.doAction(function(next){
dal.save(new Action("removed"));
});
return moreStream
.merge(lessStream)
.flatMap(function(next){
return logic.calculatePrice(dal.load(), 8.0);
})
.doAction(function(next){
view.displayNumber(next.Count);
view.displayAmount(next.Amount);
})
.subscribe();
};
var _scalable = function(){
var displayScalable = function(value){
var ul = document.getElementById("displayScalable");
var newLi = document.createElement("li");
ul.appendChild(newLi);
newLi.innerHTML = value;
}
return Rx.Observable.interval(1000)
.observeOn(Rx.Scheduler.requestAnimationFrame)
.doAction(function(){
displayScalable("map requestAnimationFrame");
})
.observeOn(Rx.Scheduler.mutationObserver)
.doAction(function(){
displayScalable("reduce mutationObserver");
})
.observeOn(Rx.Scheduler.timeout)
.doAction(function(){
displayScalable("map with timeout");
})
.observeOn(Rx.Scheduler.immediate)
.doAction(function(){
displayScalable("reduce immediate");
})
.subscribe();
};
var _resilient = function(){
var displayResilient = function(value){
var ul = document.getElementById("displayResilient");
var newLi = document.createElement("li");
ul.appendChild(newLi);
newLi.innerHTML = value;
}
function DisposableResource(value) {
var self = this,
value = null,
disposed = false;
self.getValue = function() {
if (this.disposed) {
throw new Error('Object is disposed');
}
return this.value;
};
self.dispose = function() {
if (!this.disposed) {
this.disposed = true;
this.value = null;
}
displayResilient('disposed!');
}
}
var subject = new Rx.Subject();
var binding = Rx.Observable.using(function() {
return new DisposableResource(42)
}, function(resource){
return subject.asObservable();
});
var stream = binding
// .catchException(Rx.Observable.returnValue(100))
// .onErrorResumeNext(Rx.Observable.returnValue(200))
.doAction(function(next){
displayResilient(next);
},
function(error){
displayResilient(error);
},
function(){
displayResilient("done!");
})
// .retry(3)
.finallyAction(function () {
displayResilient('finally!');
});
var subscription = stream.subscribe();
subject.onNext("1");
subject.onNext("2");
// subject.onError("error");
// subject.onCompleted();
subject.onNext("3");
subscription.dispose();
return subscription;
};
var _interactive = function(){
function searchWikipedia (term) {
var url = 'http://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=' + term + '&callback=JSONPCallback';
return Rx.DOM.Request.jsonpRequest(url);
}
function resetDisplay() {
var ul = document.getElementById('results');
while (ul.firstChild) {
ul.removeChild(ul.firstChild);
}
}
function displayResults(data){
var ul = document.getElementById('results'),
results = data[1];
resetDisplay();
for (var i = 0, len = results.length; i < len; i++) {
var li = document.createElement('li');
li.innerHTML = results[i];
ul.appendChild(li);
}
}
function displayError(error){
var ul = document.getElementById('results');
resetDisplay();
var li = document.createElement('li');
li.innerHTML = 'Error: ' + error.message;
ul.appendChild(li);
}
return Rx.DOM.fromEvent(document.getElementById('textInput'), 'keyup')
.map(function(next) {
return next.target.value;
})
.filter(function(next) {
return next.length > 2;
})
.throttle(250)
.distinctUntilChanged()
.map(function (next) {
return searchWikipedia(next);
})
.switchLatest()
.filter(function (next) {
return next.length === 2;
})
.doAction(displayResults, displayError)
.subscribe();
};
return {
EventDriven : _eventdriven,
Scalable: _scalable,
Resilient: _resilient,
Interactive: _interactive,
};
};
var activeSubscription,
samples = new Basics();
input = Rx.DOM.fromEvent(document.getElementsByTagName('li'), 'click');
input
.doAction(function(next){
if(activeSubscription) activeSubscription.dispose();
})
.doAction(function(next){
var sections = Array.prototype.slice.call(document.getElementsByTagName("section"));
sections.forEach(function(section){
section.style.display = "none";
});
})
.map(function(next){
return next.target.innerText;
})
.filter(function(next){
return next !== "";
})
.doAction(function(next){
var section = document.getElementById(next);
if(section !== null) section.style.display = "block";
})
.doAction(function(next){
activeSubscription = samples[next]();
})
.subscribe();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment