RxJs Basics Flashcards
What is an observable?
A lazily evaluated computation that may produce zero to possibly infinite values.
When creating an observable with new
or Observable.create
, what argument do you provide?
A subscriber argument which is a function that is evaluated when the observable is first subscribed to. You can call next, error, or complete in this function.
What callbacks can observers register when subscribing to an observable?
next, for handling new values
error, for handling errors
complete, for handling completion of the observable
What values are emitted by the following observable?
const observable = new Observable((subscriber) => { subscriber.next("one"); subscriber.next("two"); subscriber.complete(); subscriber.next("three"); subscriber.next("four"); });
“one” and “two”, nothing emits after the call to complete.
What alternative do you have to supplying the subscription object with next, error, and complete functions?
Pass the callbacks as parameters to overloads of the subscribe function, e.g.
observable.subscribe( value => console.log(value), null, // null for error callback () => console.log('completed') )
Do observables always deliver values asynchronously?
No, they can deliver values synchronously or asynchronously.
When you return a function from the subscriber argument passed to the Observable constructor, what is it used for?
It is run to clean up resources (e.g. timers) when the observable completes.
What is returned when you call subscribe
on an observable, and what might you use it for?
A subscription object which has: anunsubscribe
method on it that allows the consumer to declare they are done with the observable (as opposed to the producer explicitly calling complete), and a add
method which allows you to join observables together.
Is the complete callback called when you call unsubscribe on a subscription?
No, the complete callback is only called when the producer, i.e. the observable, explicitly calls complete.
How can you join multiple subscriptions together so that you can unsubscribe them all at the same time?
By calling add on the subscription object, e.g. subscriptionOne.add(subscriptionTwo)
What is a creation operator?
An operator that lifts a non-observable value or source into an observable, e.g. of(‘my value’)
How would you import the fromEvent
creation operator?
import { fromEvent } from ‘rxjs’
How would you create and subscribe to and observable that emits whenever the user clicks anywhere in the document?
import { fromEvent } from ‘rxjs’
const source$ = fromEvent(document, 'click') const sub = source$.subscribe(next => ....)
How would you use the of
creation operator to create an observable that will emit “foo”, “bar”, “baz”, in sequence?
import { of } from ‘rxjs’
const source$ = of(“foo”, “bar”, “baz”)
source$.subscribe(next => …)
What other creation operator could you use in place of of(1,2,3,4,5)
?
range(1, 5)
What would the output be when the following code is run?
import { of } from 'rxjs' const source$ = of("foo", "bar", "baz") source$.subscribe(console.log) console.log("zap")
“foo”
“bar”
“baz”
“zap”
What is the difference between of([1,2,3])
and from([1,2,3])
?
of
will emit a single array value, [1,2,3]
from
will emit the elements of the array one by one
What does the following code do?
function* hello() { yield 'Hello'; yield 'World'; }; const x = hello(); from(x).subscribe(console.log);
Creates an iterator by calling the generator function hello
. Iterators have a next
method on them that returns the yielded values. The rxjs from
creation operator can use this iterator to create a stream.
Can the from
creation operator take a Promise?
Yes
What does the interval
creation operator do?
Emits a incrementing sequence of numbers, starting at zero, at the interval you specify. e.g. interval(1000)
emits a number every second.
What does timer(2000)
do?
Emits 0 after 2 seconds, then completes.
What does timer(5000, 500)
do?
Emits 0 after 5 seconds, then emits numbers in sequence, starting at 1, every half second.
What is a ‘pipeable’ operator?
A function that takes an observable as an input, and returns another observable as an output.
How would you apply the map
operator to a observable created by of(1,2,3)
, without using the pipe
method?
map(value => …)(of(1, 2, 3))
Do rxjs pipeable operators modify the input observable?
No, they return a new observable, without altering the input/source observable.
What is a marble diagram?
A visualization of a source input, passed to a pipeable operator (or composition of operators), and the resulting output, e.g.
input$: –1—-2—-3
map(value => value * 2)
output$: –2—-4—-6
What does a solid vertical line on the output line of a marble diagram represent?
The completion of the observable
What does an X on the output line of a marble diagram represent?
An error.
Where are pipeable operators imported from?
‘rxjs/operators’
What does the map
operator do?
Applies a given projection function to each value emitted by the source observable.
What does the pluck
operator do?
Maps each source value to it’s specified nested property.
What does the mapTo
operator do?
Emits the given constant value on the output Observable every time the source Observable emits a value.
What does the filter
operator do?
Filters out values emitted by an input source that do not pass the supplied predicate function.
What does the reduce
operator do?
Accumulates emitted values in a single ‘accumulator’ value, which gets emitted when the source observable completes.
What is output when the following code is run?
interval(1000) .pipe( reduce((acc, next) => acc + next, 0) ) .subscribe({ complete: () => console.log('Complete!') });
Nothing! The reduce
operator is accumulating, but it will only emit once the source observable completes. Since interval
never completes, the reduce never emits.
What is the difference between the scan
and reduce
operators?
scan
emits a value every time the source observable emits value and reduce
only emits a value when the source observable completes.
What happens when you return a value from the tap
operator?
Nothing. The return value is ignored.
How would you use the tap
operator to console log when an observable completes?
observable$.pipe(
tap({ complete: () => console.log(‘completed’) }
)
How could you make the x$
observable complete after it receives three values from the numbers$
source?
const numbers$ = of(1,2,3,4,5) const x$ = numbers$.pipe(???).subscribe(console.log)
Use the take
pipeline operator, e.g.
const numbers$ = of(1,2,3,4,5) const x$ = numbers$.pipe(take(3)).subscribe(console.log)
Without using filter
or take
, how could you make the x$ observable emit only the number 2, then complete?
const numbers$ = of(1,2,3,4,5) const x$ = numbers$.pipe(???).subscribe(console.log)
Use the first
operator, e.g.
const numbers$ = of(1,2,3,4,5) const x$ = numbers$.pipe( first(y => y === 2) ).subscribe(console.log)
When would you use the takeWhile
operator?
When you want to limit the life of your observable, based on a predefined condition.
Explain what the takeUntil
pipeline operator does?
takeUntil(notifier: ObservableInput)
It consumes values emitted by its source observable until another observable, commonly called the notifier observable, emits a value.
What will the following code output? Why?
const numbers$ = of(1, '1', 2, 3, 3, 3, 4, 5, 3); numbers$.pipe(distinctUntilChanged()).subscribe(console.log);
output:
1, 1, 2, 3, 4, 5, 3
distinctUntilChanged
emits unique values based on a === comparison to the last emitted value. So the string ‘1’ is different to the number 1, and the 3 and the end is emitted because the previous emission was not a 3.
What does the debounceTime
operator do?
Only emits values from it’s source observable when the provided number of ms has elapsed between emissions.
Explain the following signature:
throttleTime(duration: number, scheduler: SchedulerLike = asyncScheduler, config: ThrottleConfig = defaultThrottleConfig)
Emits a value from the source Observable, then ignores subsequent source values for duration
milliseconds, then repeats this process. The final config
argument can be used to configure when in the throttle window values are emitted.
How do the debounceTime
and sampleTime
rate limiting operators differ?
debounceTime
emits a notification from the source Observable only after a particular time span has passed without another source emission.
whereas sampleTime
emits the most recently emitted value from the source within periodic time intervals.
What does the auditTime
operator do?
Ignores source values for duration
milliseconds, then emits the most recent value from the source Observable, then repeats this process.
What is a ‘flattening’ operator?
Operators that convert a higher order observable into a first-order ordinary observable (by ‘flattening’).
What does the mergeAll
operator do?
Converts a higher-order Observable into a first-order Observable which concurrently delivers all values that are emitted on the inner Observables (order not guaranteed).
What does the mergeMap
operator do?
Maps each value to an Observable, then flattens all of these inner Observables using mergeAll
.
How does the switchMap
operator differ from the mergeAll
operator?
The switchMap
operator cancels previous inner observables when the source observable emits again, whereas the mergeAll
operator emits values from multiple inner observables concurrently, leaving clean up to the programmer.
When using Observables to request data from a server via a GET request, which you then use to update the UI, would you use mergeAll
or switchMap
operator? Why?
switchMap
because you want to cancel previous requests as new source values are emitted (e.g. a type-ahead with server side lookup scenario).
What does the concatMap
operator do?
Maintains one active inner subscription by queuing inner Observables in a FIFO fashion. The next observable is activated once the previous completes.
When would you use the concatMap
operator?
When the order of execution is important and inner Observables have finite lifespans.
What does the exhaustMap
operator do?
Ignores values emitted from the source when there is an active inner Observable. The inner Observable must complete before new source emissions are handled.
What does the catchError
operator do?
Catches errors thrown by its source Observable. It can then either throw and error, or return an Observable to keep the Observable going.
What does the following code output?
of(1,2,3).pipe( startWith('a', 'b', 'c'), endWith('d', 'e', 'f') ).subscribe(console.log);
a b c 1 2 3 d e f
What does the concat
creation operator do?
It queues multiple Observables to run to completion, one after the other.
Which of the following are creation operators and which are pipeable operators?
map
concat
merge
concatMap
map
pipeableconcat
creationmerge
creationconcatMap
pipeable
What does the empty
operator do?
Creates an observable that emits no values, then completes.
What does the following code do?
merge( startClick$.pipe(mapTo(true)), pauseClick$.pipe(mapTo(false)) )
Creates an output Observable which concurrently emits all values from every given input Observable.
What does the combineLatest
operator do?
Joins multiple Observables into a single Observable that emits the most recent values from every input Observable, whenever any input Observable emits. All input Observables must emit once before any combination can be emitted.
What is the difference between the combineLatest
and withLatestFrom
operators, and when would you use each?
combineLatest
is a creation operator that takes multiple Observables and creates a single observable that emits the latest value seen from all the input streams, e.g.
combineLatest(keyup$, click$)
withLatestFrom
is a pipeable operator that combines another Observable with its single source Observable, e.g.
click$.pipe(withLatestFrom(interval(1000)))
What combination operator would you use to consume the last value before completion, across multiple Observables?
forkJoin
What does the following code do:
forkJoin({ user: ajax.getJSON(`${GITHUB_API_BASE}/users/reactivex`), repo: ajax.getJSON(`${GITHUB_API_BASE}/users/reactivex/repos`) }).subscribe(console.log);
Creates a single Observable, by combining two ajax Observables. The returned Observable emits objects with the keys provided (user and repo) once both of the ajax Observables complete.