A few days ago we covered operators that convert a Higher Order Observable into a normal Observable. Today we’ll talk about operators that convert a common Observable into a Higher Order Observable.
This type of Operators is not often used on the front end, but only on special occasions.
Operators
window
The Window is a whole family of five related Operators
- window
- windowCount
- windowTime
- windowToggle
- windowWhen
Here we only introduce the two methods of Window and windowToggle. The other three methods are relatively easy to use. You can check them on the official website if necessary.
A window is similar to a buffer that splits elements into arrays over a period of time
Observable<T> => Observable<Array<T>>Copy the code
A window splits elements into a new Observable
Observable<T> => Observable<Observable<T>>Copy the code
A buffer is a split element that is put into an array and sent out. A window is an observable that puts the split element into an Observable and sends it out. Let’s look at an example
var click = Rx.Observable.fromEvent(document.'click');
var source = Rx.Observable.interval(1000);
var example = source.window(click);
example
.switch()
.subscribe(console.log);
/ / 0
/ / 1
/ / 2
/ / 3
/ / 4
// 5 ...Copy the code
First, the window passes in an Observable. Every time the Observable sends an element, it puts the element sent by the processing observable into the new Observable and sends it. The Marble Diagram can be better explained here
click : -----------c----------c------------c--
source : ---0---- 1---2 ----- 3---4 ----- 5---- 6-.. window(click) example: o----------o----------o------------o-- \ \ \ --0---- 1-|-2 ----- 3--|4 ----- 5---- 6|
switch() : -0---- 1---2 ----- 3---4 ----- 5---- 6-...Copy the code
Here you can see that the Example becomes the sending Observable, which ends every time the click event is sent, and continues to the next Observable. Here we flatten it out with switch.
This example is intended only to express the function of window. In practice, window is used with other operators. For example, we want to count how many click events are triggered in a second
var click = Rx.Observable.fromEvent(document.'click');
var source = Rx.Observable.interval(1000);
var example = click.window(source)
example
.map(innerObservable= > innerObservable.count())
.switch()
.subscribe(console.log);Copy the code
JSBin | JSFiddle
Note that we swapped source with click and used an Observable method called count() to retrieve the total number of elements sent by the Observable, as shown in the Marble Diagram below
source: -- -- -- -- -- -- -- -- - -- -- -- -- -- -- -- -- -- 1 -- -- -- -- -- -- -- -- -- 2 -... click : --cc---cc----c-c----------------... window(source)
example: o--------o---------o---------o--..
\ \ \ \
-cc---cc|---c-c---|---------|--..
count()
: o--------o---------o---------o--
\ \ \ \
-------4|--------2|--------0|--..
switch()
: ---------4---------2---------0--...Copy the code
As can be seen from the Marble Diagram, we can make more flexible operations by putting some elements into the new Observable
windowToggle
Unlike Windows, which only controls the end of an internal Observable, windowToggle can pass in two parameters. The first is the starting Observable. The second is a callback that returns a finished Observable. Let’s look at an example
var source = Rx.Observable.interval(1000);
var mouseDown = Rx.Observable.fromEvent(document.'mousedown');
var mouseUp = Rx.Observable.fromEvent(document.'mouseup');
var example = source
.windowToggle(mouseDown, () => mouseUp)
.switch();
example.subscribe(console.log);Copy the code
JSBin | JSFiddle
The Marble Diagram will be a better explanation
source: - 0-1-2-3-4-5 -... mouseDown: -------D------------------------... mouseUp : ---------------------------U----... windowToggle(mouseDown, () => mouseUp) : -------o-------------------------... \ -1----2----3----4--| switch() example : ---------1----2----3----4---------...Copy the code
As can be seen from the Marble Diagram, we split the internal Observable by windowToggle from mouseDown to mouseUp.
groupBy
Finally, we will talk about operator-groupby, which is commonly used in development. It can help us divide elements with the same conditions into observables. In fact, it is the same concept in SQL
var source = Rx.Observable.interval(300).take(5);
var example = source
.groupBy(x= > x % 2);
example.subscribe(console.log);
// GroupObservable { key: 0, ... }
// GroupObservable { key: 1, ... }Copy the code
JSBin | JSFiddle
In the above example, we pass in a callback function and return the groupBy condition to distinguish each element into different Observables, as shown in the Marble Diagram below
source : ---0---1---2---3---4|
groupBy(x => x % 2)
example: ---o---o------------|
\ \
\ 1-------3----|
0-------2-------4|Copy the code
In fact, we can differentiate elements with groupBy and then operate an Inner Observable. For example, in the following example, we add up each person’s score and send it out
var people = [
{name: 'Anna'.score: 100.subject: 'English'},
{name: 'Anna'.score: 90.subject: 'Math'},
{name: 'Anna'.score: 96.subject: 'Chinese' },
{name: 'Jerry'.score: 80.subject: 'English'},
{name: 'Jerry'.score: 100.subject: 'Math'},
{name: 'Jerry'.score: 90.subject: 'Chinese'},];var source = Rx.Observable.from(people)
.zip(
Rx.Observable.interval(300),
(x, y) => x);
var example = source
.groupBy(person= > person.name)
.map(group= > group.reduce((acc, curr) = > ({
name: curr.name,
score: curr.score + acc.score
})))
.mergeAll();
example.subscribe(console.log);
// { name: "Anna", score: 286 }
// { name: 'Jerry', score: 270 }Copy the code
JSBin | JSFiddle
Our example here is to sum the scores of Jerry and Anna individually, and the Marble Diagram is shown as follows
source: --o--o--o--o--o--o| groupBy(person => person.name) : --i--------i------| \ \ \ o--o--o| o--o--o--| map(group => group.reduce(...) ) : --i---------i------| \ \ o| o| mergeAll() example: --o---------o------|Copy the code
Today’s summary
Today I talked about two operators that can split elements into a new Observable. These two operators are rarely used in the front end, but are more likely to be used in the back end or when they are more complex. I wonder if readers have learned anything? If you have any questions please leave a message to me, thank you.