Cascadia.js: Don't Cross the Streams
-
Upload
mattpodwysocki -
Category
Technology
-
view
3.339 -
download
0
description
Transcript of Cascadia.js: Don't Cross the Streams
![Page 1: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/1.jpg)
Don’t Cross the Streams…
Matthew Podwysocki
@mattpodwysocki
![Page 2: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/2.jpg)
![Page 3: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/3.jpg)
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
![Page 4: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/4.jpg)
The promise of a better future…
tweetsAsync()
.then(function (a) { return usersAsync(a); })
.then(function (b) { return locationAsync(b); })
.done(function (c) { render(); });
![Page 5: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/5.jpg)
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…
![Page 6: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/6.jpg)
In other words…
We cross the streams!
![Page 7: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/7.jpg)
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 concurrency
RxJS = Observables + LINQ + Schedulers
![Page 8: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/8.jpg)
Not another flow control library…
Why bother?
![Page 9: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/9.jpg)
var mousedrag = mousedown.selectMany(function (md) {
// calculate offsets when mouse downvar startX = md.offsetX,
startY = md.offsetY;
// calculate diffs until mouse upreturn mousemove.select(function (mm) {
return {left: mm.clientX - startX,top: mm.clientY - startY
};}).takeUntil(mouseup);
});
Rich Composite Events…
![Page 10: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/10.jpg)
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…
![Page 11: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/11.jpg)
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…
![Page 12: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/12.jpg)
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');
});
![Page 13: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/13.jpg)
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 concurrency
RxJS = Observables + LINQ + Schedulers
![Page 14: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/14.jpg)
The Essentials…
Observable = {subscribe :
function (observer) { … }};
Observer = {onNext :
function (data) { … },onError :
function (error) { … },onCompleted :
function () { … }};
Observable
Subscribe
Observer
![Page 15: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/15.jpg)
The Grammar Police…
• Zero or more values
• E.g. events are ∞ sequences
OnError OnCompleted
0 1 2
0 1
0 1 2
0 1 2
* ( | ) ?
• It’s a sequence
• No concurrent
callbacks
• One time termination
![Page 16: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/16.jpg)
First Class Events…
![Page 17: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/17.jpg)
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 concurrency
RxJS = Observables + LINQ + Schedulers
![Page 18: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/18.jpg)
If you know ES5 Array “extras”…
Array
• Querying
• concat
• every
• filter
• map
• reduce
• some
• Subscribing
• forEach
Observable
• Querying
• concat
• all
• where
• select
• aggregate
• any
• Subscribing
• subscribe
… then you know RxJS
![Page 19: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/19.jpg)
Querying Asynchronous Streams
• Observables are data streams
• Hence we can query them like we do with Arrays!
functionreturn
![Page 20: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/20.jpg)
Querying Asynchronous Streams
• Observables are asynchronous
• Hence, they have a notion of time
![Page 21: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/21.jpg)
Limited only by imagination…aggregate
all
amb
any
asObservable
average
buffer
bufferWithCount
bufferWithTime
bufferWithTimeOrCount
catchException
combineLatest
concat
concatObservable
contains
count
create
createWithDisposable
defaultIfEmpty
defer
delay
dematerialize
distinct
disinctUntilChanged
doAction
elementAt
elementAtOrDefault
empty
generate
generateWithAbsoluteTime
generateWithRelativeTime
groupBy
groupByUntil
groupJoin
ignoreElements
interval
join
materialize
max
maxBy
merge
mergeObservable
min
minBy
multicast
never
observeOn
onErrorResumeNext
publish
publishLast
range
refCount
repeat
replay
retry
returnValue
sample
scan
select
selectMany
sequenceEqual
skip
skipLast
skipUntil
skipWhile
start
startWith
subscribe
subscribeOn
sum
switchLatest
take
takeLast
takeLastBuffer
takeUntil
takeWhile
then
throttle
throwException
timeInterval
timeout
timer
using
when
where
window
windowWithCount
windowWithAbsoluteTime
windowWithRelativeTime
zip
![Page 22: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/22.jpg)
Creation operators
create*
empty
fromArray
generate*
never
range
repeat
returnValue
![Page 23: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/23.jpg)
Standard operators
distinct
distinctUntilChanged
groupBy
select
selectMany
skip*
take*
where
![Page 24: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/24.jpg)
Aggregation operators
aggregate
all
any
contains
count
min
max
scan
![Page 25: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/25.jpg)
Error handling operators
catchException
finallyAction
onErrorResumeNext
retry
throwException
using
![Page 26: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/26.jpg)
Complex Event operators
buffer*
groupJoin
join
window*
sample
![Page 27: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/27.jpg)
Orchestration operators
combineLatest
concat
forkJoin
merge
skipUntil
switchLatest
takeUntil
zip
![Page 28: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/28.jpg)
Time based operators
delay
interval
throttle
timeout
timeInterval
timer
timeStamp
![Page 29: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/29.jpg)
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 concurrency
RxJS = Observables + LINQ + Schedulers
![Page 30: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/30.jpg)
The Role of Schedulers…
• Key questions:
• How to run timers?
• Where to produce events?
• Need to synchronize with the UI?
• Providing one answer:
• Schedulers introduce concurrency
• Operators are parameterized by schedulers
• Provides test benefits as well
d = scheduler.schedule(function () {
// Asynchronously// running work
},1000);
Cancellation
Many implementations
Optional time
![Page 31: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/31.jpg)
Testability is King!
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),
onCompleted(500));
![Page 32: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/32.jpg)
Start using it now
> npm install rx
Node.js
http://rx.codeplex.com/
Open Source
> Install-Package RxJS
NuGet
![Page 33: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/33.jpg)
What’s Next?
• Ongoing work
• Documentation
• Tutorials
• Where’s the vision?
• Scaling
• Distributed
• Merge with Node.js Streams
![Page 35: Cascadia.js: Don't Cross the Streams](https://reader033.fdocuments.net/reader033/viewer/2022060108/554ebdceb4c9053c4b8b4796/html5/thumbnails/35.jpg)
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