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

Intro RxJs - Stream all the things

Intro RxJs - Stream all the things

Introduction to Reactive Extensions with code examples using RxJs

Mark van Straten

December 01, 2016
Tweet

More Decks by Mark van Straten

Other Decks in Programming

Transcript

  1. Value Promise<Value> Enumerable<Value> Observable<Value> (Subject/Observer is Dual to Iterator -

    Erik Meijer - http://csl.stanford.edu/~christos/pldi2010.fit/meijer.duality.pdf)
  2. A stream of future events is an Observable Listening to

    an observable is a Subscription State changes on an observable are done using Operators Concurrency is managed using Schedulers
  3. UI Interaction function onDoubleClick(target, callback) { let clicks = 0;

    let self = this; return target.on('click', () => { clicks++; if(clicks == 1) { setTimeout(() => { if(clicks === 2) { callback.call(self); } clicks = 0; }, 300); } }); const target = document.querySelector('body'); onDoubleClick(target, () => console.log(‘got doubleClick’) const target = document.querySelector('body'); const clickStream = Rx.Observable.fromEvent(target, 'click'); clickStream .buffer(clickStream.debounce(300)) .map(list => list.length) .filter(x => x == 2) .subscribe(doubleClick => console.log('got doubleClick'));
  4. API call retry logic // using observables function getUser(userId) {

    const getUserDetailsFallbacks = [ getUserFromServer(userId), getUserFromCache(userId), getEmptyUserObject(userId), ]; return Rx.Observable .catch(getUserDetailsFallbacks) .toPromise(); // optional } // using promises function getUser(userId) { return getUserFromServer(userId) .catch(err => getUserFromCache(userId) .catch(err => getEmptyUserObject(userId)) ); }
  5. I want to publish question(s) and retrieve my answer. If

    the answer is not in time throw an error.
  6. Match response to request const allAnswersStream = redis.subscribe(‘answers:*’) .map(parseAnswer); function

    getAnswerForQuestion(q) { const answerStream = allAnswersStream .filter(a => a.id === q.id); return redis.publish(‘question:${q.id}’,q) .zip(answerStream) .take(1) /* only need one answer */ .timeout(2 * 1000) /* ms */ .map(qa => qa[1]);//only need the answer }
  7. “transform the items emitted by an Observable into Observables, then

    flatten the emissions from those into a single Observable” Also known as flatMap() (http://reactivex.io/documentation/operators/flatmap.html)
  8. Start with these • map • filter • scan •

    mergeMap • switchMap • combineLatest • concat • do
  9. Seen this? describe('MyService', function() { // ... setup stuff it('Retrieves

    user details', function(done) { // increased timeout because getUser sometimes takes a long time to complete this.timeout(5000); const promise = service.getUser(1) .then(user => { expect(user).to.not.be.null; }); expect(promise).to. eventually.be.fulfilled.and.notify(done); }); });
  10. const scheduler = new Rx.TestScheduler(); const getUserFromServerStream = scheduler.createColdObservable( onNext(100,

    ({ id: 1, name: 'myUser' })), onCompleted(110) ); mocha.stub('getUserFromServer').returns(getUserFromServerStream); const results = scheduler.startScheduler( () => getUser(1) ); console.log(results.messages) // [0]=onNext(100, ({ id: 1, name: 'myUser' }))), [1]=onComplete(110)
  11. Rx is a complex tool for reducing cognitive load when

    talking about the complex problem called asynchronicity