Last active
January 20, 2016 13:06
-
-
Save josefbetancourt/52702ef5658e12e03087 to your computer and use it in GitHub Desktop.
RxJS example of reactive toggable and cancellable process loop in browser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Toggle.js RxJS example of reactive toggable and cancellable process loop | |
// By: Josef Betancourt | |
// Date: Jan 11, 2016 | |
// =========== Model | |
var counter = 1; | |
var runningState = true; | |
var msg = ''; | |
var runButtonValue = 'Start'; | |
// =========== UI | |
var render = () => { | |
$("#output").html('<b>'+msg+'</b>' + '( Counter: '+ counter + ', Flag=' + runningState + ')'); | |
setToggleButton(); | |
} | |
var setToggleButton = () => $('#toggleButton').attr('value',runButtonValue); | |
setToggleButton(); | |
// =========== Operations | |
var runOperation = function(){ | |
msg = 'Running'; | |
console.log("Performing operation ... " + counter++ + ', flag=' + runButtonValue); | |
} | |
var pauseOperation = function(){ | |
msg = 'Pausing'; | |
console.log("Performing pause ... " + counter++ + ',flag=' + runningState); | |
} | |
// =========== Inputs | |
var click$ = Rx.Observable.fromEvent($('#toggleButton'),'click').debounce(500); | |
var start$ = click$.first(); | |
var toggleState = runningState => !runningState; | |
var toggle$ = click$.scan(toggleState,runningState).startWith(runningState); | |
var disposable; | |
Rx.Observable.fromEvent($('#exitButton'),'click').subscribe( x => { | |
msg = 'Exiting'; | |
disposable.dispose(); | |
}); | |
// =========== Stream machine | |
start$.subscribe( | |
function(x){ // onNext | |
runButtonValue = 'Toggle'; | |
console.log("Starting ...."); | |
disposable = Rx.Observable.interval(1000) | |
.combineLatest(toggle$, (x,state) => { | |
runningState = state; | |
state; | |
}).finally(() => {render(); console.log('Ending stream');}) | |
.subscribe( | |
state => { | |
state ? runOperation() : pauseOperation(); | |
render() | |
}, | |
err => {console.log("Error: " + err);}, | |
() => {console.log('Completed!');} | |
); | |
}, | |
(err) => {console.log('Error: ' + err)}, | |
() => {console.log('Start completed')} | |
); | |
/** | |
* Return an Observable or a value wrapped as an Observable. | |
* From: Technique presented at | |
* http://stackoverflow.com/a/21877212/1149606 | |
*/ | |
var makeObservable = function (func) { | |
return Rx.Observable.defer(function () { | |
// execute the function and then examine the returned value. | |
// if the returned value is *not* an Rx.Observable, then | |
// wrap it using Observable.return | |
var result = model.running; | |
return result instanceof Rx.Observable ? result : Rx.Observable.return(result); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// App2.js RxJS example of reactive toggable and cancellable process loop | |
// By: Josef Betancourt | |
// Date: Jan 11, 2016 | |
console.log("In App4.js ......"); | |
// =========== Model | |
var counter = 1; | |
var runningState = true; | |
var msg = ''; | |
var runButtonValue = 'Start'; | |
// =========== UI | |
var setToggleButton = function(){$('#toggleButton').attr('value',runButtonValue)}; | |
var render = function(){ | |
$("#output").html('<b>'+msg+'</b>' + '( Counter: '+ counter + ', Flag=' + runningState + ')'); | |
setToggleButton(); | |
} | |
setToggleButton(); | |
// =========== Operations | |
var runOperation = function(flag){ | |
msg = 'Running'; | |
console.log("Performing operation ... " + counter++ + ', flag=' + flag); | |
} | |
var pauseOperation = function(flag){ | |
msg = 'Pausing'; | |
console.log("Performing pause ... " + counter++ + ',flag=' + flag); | |
} | |
// =========== Inputs | |
var click$ = Rx.Observable.fromEvent($('#toggleButton'),'click').debounce(250) | |
var start$ = click$.first(); | |
var toggleState = function(runningState){return !runningState;} | |
var toggle$ = click$.scan(toggleState,runningState).startWith(runningState); | |
var disposable; | |
Rx.Observable.fromEvent($('#exitButton'),'click').subscribe( | |
function(x){ | |
disposable.dispose(); | |
console.log("Exiting ...."); | |
msg = 'Quiting'; | |
render(); | |
} | |
); | |
// =========== Operational loop stream | |
start$.subscribe( | |
function(x){ // onNext | |
runButtonValue = 'Toggle'; | |
console.log("Starting ...."); | |
disposable = Rx.Observable.interval(1000) | |
.combineLatest(toggle$, function(x,state){ | |
runningState = state; | |
return state; | |
}) | |
.subscribe( | |
function(flag){ // onNext | |
flag ? runOperation() : pauseOperation(); | |
render(); | |
}, | |
function(err){console.log("Error: " + err);}, // onError | |
function(){console.log('Completed!');} // onCompleted | |
); | |
}, | |
function(err){console.log('Error: ' + err)}, // onError | |
function(){console.log('Start completed')} // onCompleted | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment