RxJS 5 is a ground-up rewrite of RxJS that actually began development when RxJS was in 2.0. This new version of RxJS had three basic goals:
- Better performance
- Better debugging
- Compliance with the ES7 Observable Spec
Meeting the above goals meant breaking changes to the RxJS API, and a complete rewrite means that we had opportunity to change/fix/correct things we've wanted to correct about RxJS in general.
They are similar to other language implementations of ReactiveX (e.g. RxJava).
RxJS 4 | RxJS 5 | remarks |
---|---|---|
Observer |
Subscriber implements Observer |
Observer is an interface now |
IDisposable |
Subscription |
Subscription is a class, not an interface. |
Due to wanting to comply with the ES7 Observable Spec (goal 3 above), the Observer interface (as implemented by Observers and Subjects alike) has changed.
observer.onNext(value)
->observer.next(value)
observer.onError(err)
->observer.error(err)
observer.onCompleted()
->observer.complete()
So what was once subject.onNext("hi")
is now subject.next("hi")
.
To meet the Observable spec (goal 3) dispose
had to be renamed to unsubscribe
.
var subscription = myObservable.subscribe(doSomething);
// RxJS 4: subscription.dispose();
subscription.unsubscribe();
In RxJS 4, there was the idea of a CompositeSubscription
. Now all Subscriptions are "composite".
Subscription objects have an add
and remove
method on them useful for adding and removing subscriptions
enabling "composite" subscription behavior.
RxJS 4 | RxJS 5 |
---|---|
amb |
race |
bufferWithCount |
bufferCount |
bufferWithTime |
bufferTime |
flatMap or selectMany |
mergeMap or flatMap (alias) |
flatMapFirst |
exhaustMap |
flatMapLatest |
switchMap |
flatMapWithMaxConcurrent |
mergeMap or flatMap (alias) |
fromCallback |
bindCallback |
fromNodeCallback |
bindNodeCallback |
publishValue |
publishBehavior |
replay |
publishReplay |
return or just |
of |
select |
map |
selectConcat |
concatMap |
switchFirst |
exhaust |
tap |
do |
windowWithTime |
windowTime |
windowWithCount |
windowCount |
where |
filter |
and |
- |
asObservable |
- |
average |
- |
controlled |
- |
delaySubscription |
- |
doWhile |
- |
extend |
- |
groupByUntil |
- |
groupJoin |
- |
includes |
- |
indexOf |
- |
join |
- |
jortSort |
- |
jortSortUntil |
- |
lastIndexOf |
- |
manySelect |
- |
maxBy |
- |
minBy |
- |
onErrorResumeNext |
- |
ofObjectChanges |
- |
pausable |
- |
pausableBuffered |
- |
shareReplay |
- |
shareValue |
- |
selectConcatObserver or concatMapObserver |
- |
selectManyObserver or flatMapObserver |
- |
sequenceEqual |
- |
singleInstance |
- |
skipLast |
- |
skipLastWithTime |
- |
skipUntilWithTime |
- |
slice |
- |
some |
- |
sum |
- |
takeLastBuffer |
- |
takeLastBufferWithTime |
- |
takeLastWithTime |
- |
takeUntilWithTime |
- |
tapOnNext |
- |
tapOnError |
- |
tapOnCompleted |
- |
timestamp |
- |
toMap |
- |
toSet |
- |
transduce |
- |
windowWithTimeOrCount |
- |
To reduce polymorphism and get better performance out of operators, some operators have been split into more than one operator:
RxJS 4 | RxJS 5 | |
---|---|---|
map |
map(project: function, thisArg?: any) |
map(project: function, thisArg?: any) |
map(value: any) |
mapTo(value: any) |
|
flatMap |
flatMap(project: function, resultSelector?: function) |
flatMap(project: function, resultSelector?: function) |
flatMap(value: Observable, resultSelector?: function) |
flatMapTo(value: Observable, resultSelector?: function) |
|
switchMap (aka flatMapLatest ) |
flatMapLatest(project: function, resultSelector?: function) |
switchMap(project: function, resultSelector?: function) |
flatMapLatest(value: Observable, resultSelector?: function) |
switchMapTo(value: Observable, resultSelector?: function) |
|
concatMap |
concatMap(project: function, resultSelector?: function) |
concatMap(project: function, resultSelector?: function) |
concatMap(value: Observable, resultSelector?: function) |
concatMapTo(value: Observable, resultSelector?: function) |
|
buffer |
buffer(closings: Observable) |
buffer(closings: Observable) |
buffer(closingNotifierFactory: function) |
bufferWhen(closingNotifierFactory: function) |
|
buffer(openings: Observable, closingSelector?: function) |
bufferToggle(openings: Observable, closingSelector?: function) |
|
window |
window(closings: Observable) |
window(closings: Observable) |
window(closingNotifierFactory: function) |
windowWhen(closingNotifierFactory: function) |
|
window(openings: Observable, closingSelector?: function) |
windowToggle(openings: Observable, closingSelector?: function) |
|
debounce |
debounce(durationSelector: Observable) |
debounce(durationSelector: Observable) |
debounce(delay: number, scheduler?: Scheduler) |
debounceTime(delay: number, scheduler?: Scheduler) |
|
throttle |
throttle(delay: number, scheduler?: Scheduler) |
throttleTime(delay: number, scheduler?: Scheduler) |
delay |
delay(dueTime: number|Date, scheduler?: Scheduler) |
delay(dueTime: number|Date, scheduler?: Scheduler) |
delay(subscriptionDelay?: Observable, delayDurationSelector: function) |
delayWhen(delayDurationSelector: function, subscriptionDelay?: Observable) |
The names of the Schedulers in RxJS 4 were based off of the Rx.NET implentation. Consequently, some of the names
didn't make sense in a JavaScript context (for example: currentThread
when there's only one thread anyhow).
RxJS 4 | RxJS 5 | |
---|---|---|
Rx.Scheduler.default |
Rx.Scheduler.asap |
schedules on the micro task queue |
Rx.Scheduler.currentThread |
Rx.Scheduler.queue |
schedules on a queue in the current event frame (trampoline scheduler) |
Rx.Scheduler.immediate |
undefined |
by not passing a scheduler to operators that request it, it defaults to recursive execution |
If there is a feature that used to exist in RxJS 4, but no longer does in RxJS 5, please be sure to file an issue (and preferably a PR). In your issue, please describe the use case you have for the operator so we can better understand your need and prioritize it, and/or find and alternative way to compose the desired behavior.