In all asynchronous behavior, the most troublesome is probably the UI operation, because UI is directly affect the user’s experience, if handled badly on the use of experience will be a big penalty!

UI is probably the hardest of all asynchronous behaviors to deal with, not only because it directly affects the user experience, but also because UI interactions tend to be events that are triggered at a high frequency, and the time sequence between components needs to be inconsistent, making such UI interactions impossible with promises or async/await. But it’s still easy to handle with RxJS!

The two Operators, Delay and delayWhen we will introduce today are all related to UI interaction. As our web pages become more and more like applications, UI interaction becomes more and more important. Let’s try out basic UI interaction with RxJS!

Operators

delay

Delay delays the point at which an Observable starts sending elements, as shown in the following example

var source = Rx.Observable.interval(300).take(5);

var example = source.delay(500);

example.subscribe({
    next: (value) = > { console.log(value); },
    error: (err) = > { console.log('Error: ' + err); },
    complete: (a)= > { console.log('complete'); }});/ / 0
/ / 1
/ / 2
/ / 3
/ / 4Copy the code

JSBin | JSFiddle

Of course, if you look directly at the log message, you can’t tell the difference at all

Let’s go straight to the Marble Diagram

source : --0--1--2--3--4|
        delay(500)
example: -------0--1--2--3--4|Copy the code

As can be seen from the Marble Diagram, the first time to send out an element is slower. While it may not seem useful here, it is very useful for UI manipulation.

Delay can pass data of type Date as well as milliseconds

var source = Rx.Observable.interval(300).take(5);

var example = source.delay(new Date(new Date().getTime() + 1000));

example.subscribe({
    next: (value) = > { console.log(value); },
    error: (err) = > { console.log('Error: ' + err); },
    complete: (a)= > { console.log('complete'); }});Copy the code

JSBin | JSFiddle

This also seems to be used to make programs die on scheduled dates. 233

delayWhen

DelayWhen works much like Delay, except that delayWhen affects every element and requires a callback and an Observable, as shown in the following example

var source = Rx.Observable.interval(300).take(5);

var example = source
              .delayWhen(
                  x= > Rx.Observable.empty().delay(100 * x * x)
              );

example.subscribe({
    next: (value) = > { console.log(value); },
    error: (err) = > { console.log('Error: ' + err); },
    complete: (a)= > { console.log('complete'); }});Copy the code

JSBin | JSFiddle

Here is our Marble Diagram

source : --0--1--2--3--4|
    .delayWhen(x => Rx.Observable.empty().delay(100 * x * x));
example: --0---1----2-----3-----4|Copy the code

The x passed in here is every element sent by the source, so we can delay each one.

Here we use delay to make a small function, this function is very simple to let multiple photos follow the mouse run, but each photo can not run as fast!

First we prepare six headshots and write them in HTML

<img src="https://res.cloudinary.com/dohtkyi84/image/upload/c_scale,w_50/v1483019072/head-cover6.jpg" alt="">
<img src="https://res.cloudinary.com/dohtkyi84/image/upload/c_scale,w_50/v1483019072/head-cover5.jpg" alt="">
<img src="https://res.cloudinary.com/dohtkyi84/image/upload/c_scale,w_50/v1483019072/head-cover4.jpg" alt="">
<img src="https://res.cloudinary.com/dohtkyi84/image/upload/c_scale,w_50/v1483019072/head-cover3.jpg" alt="">
<img src="https://res.cloudinary.com/dohtkyi84/image/upload/c_scale,w_50/v1483019072/head-cover2.jpg" alt="">
<img src="https://res.cloudinary.com/dohtkyi84/image/upload/c_scale,w_50/v1483019072/head-cover1.jpg" alt="">Copy the code

Change img to a circle using CSS, add rim and absolute position

img{
  position: absolute;
  border-radius: 50%;
  border: 3px white solid;
  transform: translate3d(0, 0); }Copy the code

So let’s do JS again, so let’s do DOM first

var imgList = document.getElementsByTagName('img');Copy the code

The second step is to build an Observable

var movePos = Rx.Observable.fromEvent(document.'mousemove')
.map(e= > ({ x: e.clientX, y: e.clientY }))Copy the code

Step 3 Write the logic

function followMouse(DOMArr) {
  const delayTime = 600;
  DOMArr.forEach((item, index) = > {
    movePos
      .delay(delayTime * (Math.pow(0.65, index) + Math.cos(index / 4)) / 2)
      .subscribe(function (pos){
        item.style.transform = 'translate3d(' + pos.x + 'px, ' + pos.y + 'px, 0)';
      });
  });
}

followMouse(Array.from(imgList))Copy the code

Here we pass in followMouse() after transferring imgList from Collection to Array, and use forEach to fetch each OMG and index to achieve different delay times. The logic of this delay time we can think of their own, do not have to like me, finally subscribe to complete!

The last complete example is here

Today’s summary

Today we have introduced two Operators with a small example, both of which are very useful in UI operation, and we will continue to talk about several operators that can be used to optimize events with high frequency.