Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Bending time with RxJS

Bending time with RxJS

A pratical introduction to RxJS. Presentation given at the Reactive Amsterdam meetup on the 2nd December of 2015

Sergi Mansilla

December 03, 2015
Tweet

More Decks by Sergi Mansilla

Other Decks in Programming

Transcript

  1. Bending time with RxJS A practical introduction to Reactive Extensions

    by sergi mansilla | @sergimansilla Reactive Amsterdam, 2nd December 2015
  2. var clicks = 0; document.addEventListener('click', function register(e) { if (clicks

    < 10) { if (e.clientX > innerWidth / 2) { console.log(e.clientX, e.clientY); clicks += 1; } } else { document.removeEventListener('click', register); } });
  3. var clicks = 0; document.addEventListener('click', function register(e) { if (clicks

    < 10) { if (e.clientX > innerWidth / 2) { console.log(e.clientX, e.clientY); clicks += 1; } } else { document.removeEventListener('click', register); } });
  4. var clicks = 0; document.addEventListener('click', function register(e) { if (clicks

    < 10) { if (e.clientX > innerWidth / 2) { console.log(e.clientX, e.clientY); clicks += 1; } } else { document.removeEventListener('click', register); } });
  5. var clicks = 0; document.addEventListener('click', function register(e) { if (clicks

    < 10) { if (e.clientX > innerWidth / 2) { console.log(e.clientX, e.clientY); clicks += 1; } } else { document.removeEventListener('click', register); } });
  6. var clicks = 0; document.addEventListener('click', function register(e) { if (clicks

    < 10) { if (e.clientX > innerWidth / 2) { console.log(e.clientX, e.clientY); clicks += 1; } } else { document.removeEventListener('click', register); } });
  7. var clicks = 0; document.addEventListener('click', function register(e) { if (clicks

    < 10) { if (e.clientX > innerWidth / 2 && isAPressed) { console.log(e.clientX, e.clientY); clicks += 1; } } else { document.removeEventListener('click', register); } }); var isAPressed = false; document.addEventListener('keydown', e => { isAPressed = e.keyCode === 65; }, false); document.addEventListener('keyup', e => { isAPressed = false; }, false);
  8. var clicks = 0; document.addEventListener('click', function register(e) { if (clicks

    < 10) { if (e.clientX > innerWidth / 2 && isAPressed) { console.log(e.clientX, e.clientY); clicks += 1; } } else { document.removeEventListener('click', register); } }); var isAPressed = false; document.addEventListener('keydown', e => { isAPressed = e.keyCode === 65; }, false); document.addEventListener('keyup', e => { isAPressed = false; }, false);
  9. var clicks = 0; document.addEventListener('click', function register(e) { if (clicks

    < 10) { if (e.clientX > innerWidth / 2) { console.log(e.clientX, e.clientY); clicks += 1; } } else { document.removeEventListener('click', register); } }); Where is my handler??
  10. var y = f(x); var z = g(y); fAsync(x).then(...); gAsync(y).then(...);

    res = stocks // array .filter(q => q.symbol == 'FB') .map(q => q.quote) res.forEach(x => ... res = stocks // async anything .filter(q => q.symbol == 'FB') .map(q => q.quote) res.subscribe(x => ... Sync Sync Promises RxJS
  11. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    .filter(n => n % 2) .map(n => 'item ' + n) .forEach(n => console.log(n)) // "item 1" // "item 3" // "item 5" // "item 7" // "item 9"
  12. var clicks = 0; document.addEventListener('click', function register(e) { if (clicks

    < 10) { if (e.clientX > innerWidth / 2) { console.log(e.clientX, e.clientY); clicks += 1; } } else { document.removeEventListener('click', register); } }); Filter Limit to 10 Print the coordinates
  13. fromEvent(document, 'click') .filter(c => c.clientX > innerWidth / 2 })

    .take(10) .subscribe(c => console.log(c.clientX, c.clientY) })
  14. fromEvent(document, 'click') .filter(c => c.clientX > innerWidth / 2 })

    .take(10) .subscribe(c => console.log(c.clientX, c.clientY) }) Create Observable
  15. fromEvent(document, 'click') .filter(c => c.clientX > innerWidth / 2 })

    .take(10) .subscribe(c => console.log(c.clientX, c.clientY) }) Create filtered Observable
 from the first one
  16. fromEvent(document, 'click') .filter(c => c.clientX > innerWidth / 2 })

    .take(10) .subscribe(c => console.log(c.clientX, c.clientY) }) Create final Observable
 taking only first 10 results
  17. fromEvent(document, 'click') .filter(c => c.clientX > innerWidth / 2 })

    .take(10) .subscribe(c => console.log(c.clientX, c.clientY) }) Actually kick off computation
  18. // Creates an observable sequence of 5 integers var source

    = Rx.Observable.range(1, 5) // Prints out each item var subscription = source.subscribe( x => { console.log('onNext: ' + x) }, e => { console.log('onError: ' + e.message) }, () => { console.log('onCompleted') }) // => onNext: 1 // => onNext: 2 // => onNext: 3 // => onNext: 4 // => onNext: 5 // => onCompleted
  19. // Search Wikipedia for a given term function searchWikipedia(term) {

    var cleanTerm = global.encodeURIComponent(term); var url = 'http://en.wikipedia.org/w/api.php?...'; return Rx.Observable.getJSONPRequest(url); } // Get all distinct key up events from the input and var keyup = fromEvent(input, 'keyup') .map(e => e.target.value) .where(text => text.length > 2) // Longer than 2 chars .throttle(200) // Pause for 200ms .distinctUntilChanged(); // Only if the value has changed var doSearch = keyup .flatMap(text => searchWikipedia(text)) // Search wikipedia .switch() // Ensure no out of order results doSearch.subscribe(results => { // Do stuff with the results! });
  20. // Search Wikipedia for a given term function searchWikipedia(term) {

    return fromArray(['JavaScript', 'JavaServer Pages', 'JavaSoft', 'JavaScript library', 'JavaScript Object Notation', 'JavaScript engine', 'JavaScriptCore']); } // Get all distinct key up events from the input and var keyup = fromEvent(input, 'keyup') .map(e => e.target.value) .where(text => text.length > 2) // Longer than 2 chars .throttle(200) // Pause for 200ms .distinctUntilChanged(); // Only if the value has changed
  21. 0 1 merge 1 0 0 1 A B C

    3 2 0 1 3 2 100ms 200ms
  22. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    .filter(n => n % 2) .map(n => 'item ' + n) .forEach(n => console.log(n)) // "item 1" // "item 3" // "item 5" // "item 7" // "item 9"
  23. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    .filter(n => n % 2) .map(n => 'item ' + n) .forEach(n => console.log(n)) // "item 1" // "item 3" // "item 5" // "item 7" // "item 9" loop loop loop
  24. fromArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

    .filter(n => n % 2) .map(n => n * 100) .map(n => 'item ' + n) .subscribe(n => console.log(n))
  25. /** @jsx hJSX */ import Cycle from '@cycle/core'; import {makeDOMDriver,

    hJSX} from '@cycle/dom'; function main(drivers) { return { DOM: drivers.DOM.select('input').events('click') .map(ev => ev.target.checked) .startWith(false) .map(toggled => <div> <input type="checkbox" /> Toggle me <p>{toggled ? 'ON' : 'off'}</p> </div> ) }; } let drivers = { DOM: makeDOMDriver('#app') }; Cycle.run(main, drivers);