Cascadia.js: Don't Cross the Streams

23,392 views

Published on

Introduction to the Reactive Extensions for JavaScript at Cascadia JS 2012

Published in: Technology
0 Comments
14 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
23,392
On SlideShare
0
From Embeds
0
Number of Embeds
16,391
Actions
Shares
0
Downloads
72
Comments
0
Likes
14
Embeds 0
No embeds

No notes for slide

Cascadia.js: Don't Cross the Streams

  1. 1. Don’t Cross the Streams…Matthew Podwysocki@mattpodwysocki
  2. 2. Callback Hell…app.get(/index, function (req, res, next) { User.get(req.params.userId, function (err, user) { if (err) next(err); db.find({user: user.name}, function (err, cursor) { if (err) next(err); cursor.toArray(function (err, items) { if (err) next(err); res.send(items); }); }); });}); …and the Pyramid of Doom
  3. 3. The promise of a better future…tweetsAsync() .then(function (a) { return usersAsync(a); }) .then(function (b) { return locationAsync(b); }) .done(function (c) { render(); });
  4. 4. What about events?• What about composition?• How do I clean up handlers?• How do I merge streams?• Or filter?• Or aggregate?• Without having a lot of state hanging around?• The list goes on and on…
  5. 5. In other words… We cross the streams!
  6. 6. What is it?• RxJS is… • a set of types representing asynchronous data streams • a set of operators over asynchronous data streams • a set of types to parameterize concurrencyRxJS = Observables + LINQ + Schedulers
  7. 7. Not another flow control library… Why bother?
  8. 8. var mousedrag = mousedown.selectMany(function (md) { // calculate offsets when mouse down var startX = md.offsetX, startY = md.offsetY; // calculate diffs until mouse up return mousemove.select(function (mm) { return { left: mm.clientX - startX, top: mm.clientY - startY }; }).takeUntil(mouseup);}); Rich Composite Events…
  9. 9. var words = Rx.Observable.fromEvent(input, "keyup") .select(function(x) { return input.value; }) .throttle(500) .distinctUntilChanged() .select(function(term) { return search(term); }) .switchLatest();words.subscribe(function (data) { // Bind data to the UI}); Control Flow…
  10. 10. stockTicks .groupBy(function (tick) { return tick.symbol; }) .selectMany( function (g) { return g.bufferWithCount(2, 1); }, function (g, b) { return { key: g.key, b: b }; }) .select(function (c) { return { diff: (c.b[1] – c.b[0]) / c.b[0], symbol: c.key }; }) .where(function (c) { return c.diff > 0.1; }) .select(function (c) { return { company: c.symbol, increase: c.diff }; }); Complex Event Processing…
  11. 11. var sequence = 38,38,40,40,37,39,37,39,66,65;var keyups = Rx.Observable.fromEvent(document, keyup) .select(function (x) { return x.keyCode; }) .bufferWithCount(10, 10) .subscribe(function (x) { var matches = x.join() === sequence; if (matches) console.log(Konami); });
  12. 12. What is it?• RxJS is… • a set of types representing asynchronous data streams • a set of operators over asynchronous data streams • a set of types to parameterize concurrencyRxJS = Observables + LINQ + Schedulers
  13. 13. The Essentials…Observer = { onNext : function (data) { … }, Observable = { onError : subscribe : function (error) { … }, function (observer) { … } onCompleted : }; function () { … }}; Observable Subscribe Observer
  14. 14. The Grammar Police…• Zero or more values * ( OnError | OnCompleted ) ?• E.g. events are ∞ sequences 0 1 2 0 1 • It’s a sequence 0 1 2 • No concurrent callbacks • One time termination 0 1 2
  15. 15. First Class Events…
  16. 16. What?• RxJS is… • a set of types representing asynchronous data streams • a set of operators over asynchronous data streams • a set of types to parameterize concurrencyRxJS = Observables + LINQ + Schedulers
  17. 17. If you know ES5 Array “extras”…Array Observable• Querying • Querying • concat • concat • every • all • filter • where • map • select • reduce • aggregate • some • any• Subscribing • Subscribing • forEach • subscribe … then you know RxJS
  18. 18. Querying Asynchronous Streams• Observables are data streams • Hence we can query them like we do with Arrays! functionreturn
  19. 19. Querying Asynchronous Streams• Observables are asynchronous • Hence, they have a notion of time
  20. 20. Limited only by imagination…aggregate generateWithRelativeTime selectManyall groupBy sequenceEqualamb skip groupByUntil skipLastany groupJoin skipUntilasObservable skipWhileaverage ignoreElements interval startbuffer startWith join subscribebufferWithCountbufferWithTime materialize subscribeOn max sumbufferWithTimeOrCount switchLatestcatchException maxBy takecombineLatest merge takeLastconcat mergeObservable takeLastBufferconcatObservable min takeUntilcontains minBy takeWhilecount multicast thencreate throttle never throwExceptioncreateWithDisposabledefaultIfEmpty observeOn timeInterval onErrorResumeNext timeoutdefer timerdelay publish usingdematerialize publishLast whendistinct range wheredisinctUntilChanged refCount windowdoAction repeat windowWithCountelementAt windowWithAbsoluteTimeelementAtOrDefault replay windowWithRelativeTimeempty retry zipgenerate returnValuegenerateWithAbsoluteTime sample scan select
  21. 21. Creation operators create* empty fromArray generate* never range repeat returnValue
  22. 22. Standard operators distinct distinctUntilChanged groupBy select selectMany skip* take* where
  23. 23. Aggregation operators aggregate all any contains count min max scan
  24. 24. Error handling operators catchException finallyAction onErrorResumeNext retry throwException using
  25. 25. Complex Event operators buffer* groupJoin join window* sample
  26. 26. Orchestration operators combineLatest concat forkJoin merge skipUntil switchLatest takeUntil zip
  27. 27. Time based operators delay interval throttle timeout timeInterval timer timeStamp
  28. 28. What?• RxJS is… • a set of types representing asynchronous data streams • a set of operators over asynchronous data streams • a set of types to parameterize concurrencyRxJS = Observables + LINQ + Schedulers
  29. 29. The Role of Schedulers… Many implementations• Key questions: Cancellation • How to run timers? • Where to produce events? d = scheduler.schedule( function () { • Need to synchronize with the UI? // Asynchronously // running work• Providing one answer: }, • Schedulers introduce concurrency 1000); • Operators are parameterized by schedulers Optional time • Provides test benefits as well
  30. 30. var scheduler = new TestScheduler();var input = scheduler.createColdObservable( onNext(300, "Cascadia"), onNext(400, "JS"), onCompleted(500));var results = scheduler.startWithCreate(function () { input.select(function (x) { return x.length; })});results.messages.assertEqual( onNext(300, 8), onNext(400, 2), Testability is King! onCompleted(500));
  31. 31. Start using it nowNode.js> npm install rxNuGet> Install-Package RxJSOpen Sourcehttp://rx.codeplex.com/
  32. 32. What’s Next?• Ongoing work • Documentation • Tutorials• Where’s the vision? • Scaling • Distributed • Merge with Node.js Streams
  33. 33. Cross the Streams…Matthew Podwysocki@mattpodwysockimatthewp@microsoft.com
  34. 34. Credits• Cross the Streams - https://oshea12566.wordpress.com/2012/02/20/jeep-meeting-and- trail-ride/• NES Controller - http://en.wikipedia.org/wiki/File:NES-controller.jpg

×