Weitere ähnliche Inhalte Ähnlich wie RxJS Evolved (20) Kürzlich hochgeladen (20) RxJS Evolved8. FUNCTIONS
// The “idea” of a random number
var getRandomNumber = function() {
return Math.random();
}
// A random number
var rand = getRandomNumber.call();
(LAZINESS)
10. var randomNumbers = Observable.create((s) => {
var i = setTimeout(() => {
s.next(Math.random());
s.complete();
}, 1000);
return () => clearTimeout(i);
});
var sub = randomNumbers.subscribe({
next(x) { console.log(x); },
error(e) { console.error(e); },
complete() { console.log(“done”); }
});
var randomNumbers = Observable.create((s) => {
var i = setTimeout(() => {
s.next(Math.random());
s.complete();
}, 1000);
return () => clearTimeout(i);
});
var randomNumbers = Observable.create((s) => {
var i = setTimeout(() => {
s.next(Math.random());
s.complete();
}, 1000);
ANATOMY OF OBSERVABLE
★ CREATION
★ SUBSCRIPTION
★ DISPOSAL
var randomNumbers = Observable.create(
11. WHAT HAPPENS WHEN…
var randomNumbers = Observable.create((s) => {
var i = setTimeout(() => {
s.next(Math.random());
s.complete();
}, 1000);
return () => clearTimeout(i);
});
randomNumbers.subscribe(x => console.log(‘1: ’ + x));
randomNumbers.subscribe(x => console.log(‘2: ’ + x));
14. “Observable is a function that,
when invoked, returns 0-∞ values
between now and the end of time.”
–ME
16. OPERATORS
METHODS THAT PERFORM
CALCULATIONS ON THE VALUES
MAP, FILTER, SCAN, REDUCE, FLATMAP, ZIP,
COMBINELATEST, TAKE, SKIP, TIMEINTERVAL,
DELAY, DEBOUNCE, SAMPLE, THROTTLE, ETC.
18. WRITING AN OPERATOR (OLD)
class Observable {
constructor(subscribe) { this.subscribe = subscribe; }
map(selector) {
var source = this;
return new Observable((destination) => {
return source.subscribe({
next(x) { destination.next(selector(x)) },
error(e) { destination.error(e); },
complete() { destination.complete(); }
});
});
}
}
19. USING OPERATORS
var grades = { “a”: 100, “b+”: 89, “c-“: 70 };
Observable.of(“a”, “b+”, “c-”)
.map((grade) => grades[grade])
.filter((score) => score > grades[“b+”])
.count()
.subscribe((scoreCount) => {
console.log(scoreCount + “ students received A’s”);
});
22. USING SCHEDULERS
Observable.range = function(start, length, scheduler) {
return new Observable((subscriber) => {
return scheduler.schedule(({ index, count }) => {
if (subscriber.isUnsubscribed) { return; }
else if (index >= end) {
subscriber.complete();
} else {
subscriber.next(count);
this.schedule({ index: index + 1, count: count + 1 });
}
}, { index: 0, count: start });
});
}
28. import Observable from ‘@reactivex/rxjs/Observable’;
import ArrayObservable from
‘@reactivex/rxjs/observables/ArrayObservable’;
import reduce from ‘@reactivex/rxjs/operators/reduce’;
Observable.of = ArrayObservable.of;
Observable.prototype.reduce = reduce;
Observable.of(1, 2, 3, 4, 5)
.reduce((acc, i) => acc * i, 1)
.subscribe((result) => console.log(result));
MODULARITY
39. PERFORMANCE + DEBUGGING
★ SCHEDULERS OVERHAUL
★ CLASS-BASED OPERATORS (“LIFT”)
★ UNIFIED OBSERVER + SUBSCRIPTION
★ FLATTENED DISPOSABLE TREE
★ REMOVE TRY-CATCH FROM INTERNALS
40. FLATMAP VS. LIFT
flatMap<T, R>(selector: (value: T) => Observable<R>): Observable<R>;
lift<T, R>(operator: (subscriber: Observer<T>) => Observer<R>): Observable<R>;
41. FLATMAP
Observable.prototype.map = function map(project) {
var source = this;
return new Observable(function (observer) {
return source.subscribe(
(x) => observer.next(project(x)),
(e) => observer.error(e),
( ) => observer.complete()
);
});
}
★ CLOSURE SCOPE
★ INFLEXIBLE TYPE
★ CLOSURES SHOULD
BE ON A PROTOTYPE
42. Observable.prototype.map = function(project) => {
return this.lift(new MapOperator(project));
}
class MapOperator implements Operator {
constructor(project) { this.project = project; }
call(observer) {
return new MapSubscriber(observer, this.project);
}
}
class MapSubscriber extends Subscriber {
constructor(destination, project) {
super(destination);
this.project = project;
}
next(x) { this.destination.next(this.project(x)); }
}
★ NO CLOSURES
★ DELEGATES NEW
OBSERVABLE TO LIFT
★ USES SUBSCRIBER
PROTOTYPE
LIFT
44. SUBCLASS OBSERVABLE
class MouseObservable extends Observable {
constructor(source, operator) {
this.source = source;
this.operator = operator || ((x) => x);
}
lift(operator) { return new MouseObservable(this, operator); }
trackVelocity() {
return this.lift((destination) => {
return new VelocityScanningSubscriber(destination);
});
}
concatFrictionEvents(coefficientOfKineticFriction) { ... }
}
46. MAINTAIN TWO-WAY SUBJECTS
var naviSocket = new SocketSubject(“ws://127.0.0.1/navi”)
.map(x => JSON.parse(x.data))
.throttle(100);
naviSocket.subscribe((msg) => {
if (msg == “hey, listen!”) {
naviSocket.next(“go away navi!”);
}
});
48. SIMPLER UNIT TESTS
MARBLE DIAGRAMS AS UNIT TESTS
it('should filter out even values', function() {
var source = hot('--0--1--2--3--4--|');
var expected = '-----1-----3-----|';
expectObservable(source.filter(x => x % 2 == 1)).toBe(expected);
});