Observables
Q1: What is the difference between an observable and a promise?
=>The key differences are as follows:
1)Observable does not start untill subscription/subscribed, while Promises are executed immediately.
2)Observable provide many values while Promises provide one.
3)Observable subscription are cancellable while promise are not cancellable.
4)Observable provide operators to transform data. We use pipe to chain operators and only subs
We should use promises over Observables when we need single subcription on single event.
Q2: What is the difference between an observable and a subject?
=>Observable can unicast while subject is a multicast observable. It means Subject allows values to be multicasted to multiple observables.
Q3: What are some of the angular apis that are using observables?
=>http, EventEmitter, async pipe etc
Q4: How would you cache an observable data?
=>We can use create a service implementing Replay subject. A replay subject can record given no of values and then replays them to new subscribers.
Const subject = new ReplaySubject(3); //This can record 3 values.
Another way is by using publishReplay and refCount operators.
const observable$ = from(['first', 'last']).pipe(
publishReplay(1), //it will hold last one value.
refCount()
)
publishReplay creates a ReplaySubject. refCount keeps the Observable alive as long as there are any Subscribers.
[Refer]-https://medium.com/angular-in-depth/fastest-way-to-cache-for-lazy-developers-angular-with-rxjs-444a198ed6a6
Q5:How would you implement a multiple api calls that needs to happen in order using rxjs?
=>use concatMap operator(will finish the mapping before taking another input).
Q6: What is the difference between switchMap, concatMap and mergeMap?
=>mergeMap: Keep subscribing to any new observable that is returned from map
switchMap: Unsubscribe from the last observable when new one arrive
concatMap: Queue up new observable and subscribe to new one only when last one gets complete
ExhaustMap: will ignore any new observable untill last one is emitting values.
Q7: How would you make sure an api call that needs to be called only once but with multiple conditions. Example: if you need to get some data in multiple routes but, once you get it, you can reuse it in the routes that needs it, therefor no need to make another call to your backend apis.
Q8: How would you implement a brush behavior using rxjs?
Q9: How would you implement a color picker with rxjs?
Q10: If you need to respond to two different Observable/Subject with one callback function, how would you do it?(ex: if you need to change the url through route parameters and with prev/next buttons).
Q11: What is the difference between scan() vs reduce() ?
Observable are used in angular to event handling, async programming and handling multiple values.
Observer design pattern is useful in situations when we need to perform multiple operations on a single event being fired.
We create Observable instance, which contains the subscriber function. This function is executed when consumer call the subscribe() method. The subscriber method define how to generate value or pass message to be published.
Hot vs cold Observable:
A cold observable is where data is created inside it.
const cold = new Observable(observer => {
observer.next(Math.random())
});
cold.subscribe(a => console.log(`Subscriber A: ${a} `));
cold.subscribe(b => console.log(`Subscriber B: ${b} `));
The Output will be:
Subscriber A: 0.443748484
Subscriber B: 0.754754854
Here each subscriber gets different number.
A Hot observable is where data is created outside of it.
const x = Math.random();
const hot = new Observable(observer => {
observer.next(x)
});
hot.subscribe(a => console.log(`Subscriber A: ${a} `));
hot.subscribe(b => console.log(`Subscriber B: ${b} `));
The Output will be:
Subscriber A: 0.443748484
Subscriber B: 0.443748484
Here each subscriber gets same number. We can convert cold observable to hot via calling publish method like:
const cold = new Observable(observer => {
observer.next(Math.random())
});
const hot = cold.publish();
hot.subscribe(a => console.log(`Subscriber A: ${a} `));
hot.subscribe(b => console.log(`Subscriber B: ${b} `));
Now The Output will be:
Subscriber A: 0.443748484
Subscriber B: 0.443748484
publish method returns a connected observable and emit values to subscribers.
Operators:
const numbers = of(10, 100, 1000);
map: transform the values
numbers
.map(num => Math.log(num))
.subscribe(x => console.log(x));
do: execute the code without affecting the underlying observable.
const names = of('Dev', 'Jen');
names
.do(n => console.log(n))
.map(n => n.toUppercase())
.do(n => console.log(n))
.subscribe()
Output: Dev
Dev
Jen
JEN
filter: filter the values based on the condition
const numbers = of(-1, 2, 4, -7, 8, -3, 5);
numbers
.filter(num => num >=0)
.subscribe(x => console.log(x));
Output: 2
4
8
5
first/last: returns the first and last values from observable.
const numbers = of(-1, 2, 4, -7, 8, -3, 5);
numbers
.first()
.subscribe(x => console.log(x));
Output: -1
debaunce/throttle: Used in events, to limit values. As events may emit way more values than we actually needed.
const mouseEvent = fromEvent(document, 'mouseover');
mouseEvent
.throttleTime(1000)
.subscribe(event, console.log(event.type));
Output: mousemove(It will be printed repeatedly after 1 sec as we move mouse)
Without throttleTime mousemove would have been printed continuously.
debounceTime(1000) will wait for 1 sec and emit the most recent event. It can be useful in auto-complete form
Scan: works just like the array reduce function. It keeps the record of value
const event = fromEvent(document, 'click');
event
.map(e => parseInt(Math.random()*10))
.do(n => console.log(`clicked score +${n}`))
.scan((highestScore, score) => highestScore + score)
.subscribe(highestScore => console.log(`highest score ${highestScore}`))
Output:
clicked score +1
highest score 1
clicked score +1
highest score 2
clicked score +6
highest score 8
SwitchMap: Returns a observable that emit values based on applying the function on each item emitted by source.
const numbers = of(1,2,3);
numbers
.switchMap(n => { of(n, n^2, n^3) })
.subscribe(n => console.log(n))
Output:
1
1
1
2
4
8
3
9
81
In above example switchMap returns a new inner observable based on the numbers observable. The new inner observable emits the values based on the function it applied on the values it has received from the numbers observable.
const event = ofEvent(document, 'click')
event
.switchMap(e => interval(1000)) //interval observable emits value at certain interval(here after 1 second)
.subscribe(i => console.log(i))
Output: it will start printing values from 1 after each second. As we click the counter is reset.
Here also, a new inner observable is returned based on the event observable.
finally:
takeUntill: it lets pass the values untill second observable notifier emit the value.
const source = interval(1000);
const clicks = fromEvent(document, 'click');
const result = source.pipe(takeUntil(clicks));
result.subscribe(x => console.log(x));
Output: it will start printing values from 1 after each second untill first click.
takeWhile: let observable to run untill certain condition is fulfilled. Or it let take values from source untill certain condition is not met.
const clicks = fromEvent(document, 'click');
const result = clicks.pipe(takeWhile(ev => ev.clientX > 200));
result.subscribe(x => console.log(x));
Output: it will start printing values from 1 after each second untill clickX property of click event is greater than 200.
zip: combine multiple observables to create one observable.
let age$ = of<number>(27, 25, 29);
let name$ = of<string>('Foo', 'Bar', 'Beer');
let isDev$ = of<boolean>(true, true, false);
zip(age$, name$, isDev$).pipe(
map(([age, name, isDev]) => ({ age, name, isDev })),
)
.subscribe(x => console.log(x));
Output:
{ age: 27, name: 'Foo', isDev: true }
{ age: 25, name: 'Bar', isDev: true }
{ age: 29, name: 'Beer', isDev: false }
forkJoin: it will wait for Observables to complete and then combine last values they emitted.
const observable = forkJoin({
foo: of(1, 2, 3, 4),
bar: Promise.resolve(8),
baz: timer(4000),
});
observable.subscribe({
next: value => console.log(value),
complete: () => console.log('This is how it ends!'),
});
Output:
{ foo: 4, bar: 8, baz: 0 } after 4 seconds
"This is how it ends!" immediately after
For all above content [Refer]-https://www.youtube.com/watch?v=2LCo926NFLI
Async/Await [Refer] - https://javascript.info/async-await
Observable quick tutorials [Refer]- http://reactivex.io/rxjs/manual/overview.html#introduction
Comments
Post a Comment