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.