Four other implementations of RxJS

The cause of

The reason why I think of this library is that I saw the Callbag library. You can find the principle of the Callbag library by yourself. I will not repeat it, but I will talk about my understanding. Callbag is designed to combine consumers and producers into one and communicate by passing a callback function to each other. For those of you who have seen how some of these operators work, the logic must be very difficult to understand, because you are running out of brain circuits with too many callbacks. After I used some library functions, I realized that there was no need for such a complicated design. Why? See below

Much the same callbag

There is a lot of code in callbag is written repeatedly, the reason is very simple, the function is determined, such as subscription function, this is essential operation, let me compare my library implementation and callbag implementation.

Compare to implement producer interval

Callbag source code first

const interval = period= > (start, sink) => {
  if(start ! = =0) return;
  let i = 0;
  const id = setInterval((a)= > {
    sink(1, i++);
  }, period);
  sink(0, t => {
    if (t === 2) clearInterval(id);
  });
};

export default interval;
Copy the code

explain

if(start! =0)return
Copy the code

This sentence can be found everywhere in the Callbag implementation library. It is because of this sentence that I think, why do I repeat it every time? Of course, because this is a producer, it only sends data, it doesn’t receive data.

  sink(0, t => {
    if (t === 2) clearInterval(id);
  });
Copy the code

The above code actually implements an unsubscribe function by passing back a callback to the passed callback, which will probably burn your brain.

The interval observable prototype above represents most callbag cases, so is there a way to implement it in a more concise way?

ShowTime

exports.interval = period= > n => {
    let i = 0;
    const id = setInterval((a)= > n(i++), period)
    return (a)= > clearInterval(id)
}
Copy the code

What, just a few lines of code? Yes, this is the library that I think has the smallest implementation code. This code is small, high-performance, and easy to understand. Of course, I have to explain a little bit that in order for interval(1000) to be a real producer, you have to be able to subscribe, you have to be able to unsubscribe, and you have to be able to get the data that the producer sends (some of which also need to get complete and error events, Interval will not complete or error.

  • interval(1000)I’m going to get a functionN = >..., which takes a next function to send data
  • callinterval(1000)This higher-order function is equivalent to “subscribe”, which is important here (instead of sending type 0 in callbag)
  • Dispose (instead of a callbag that returns a callback and accepts type 2)
  • The incoming next function n is called, and the data is sent

Of course interval doesn’t work on its own, we need more operators and observers to make the library work.

The filter comparison operator

Here is the implementation of callbag

const filter = condition= > source => (start, sink) = > {
  if(start ! = =0) return;
  let talkback;
  source(0, (t, d) => {
    if (t === 0) {
      talkback = d;
      sink(t, d);
    } else if (t === 1) {
      if (condition(d)) sink(t, d);
      else talkback(1);
    }
    else sink(t, d);
  });
};

module.exports = filter;
Copy the code

It still shows up

if(start! =0)return
Copy the code

Yes, because the filter is only used to be subscribed, and is itself a data responder, some people say no, the filter needs to respond to the source at the upper level, yes, so you need to subscribe to the source at the upper level, but instead of passing in itself, you need another callback function to respond, otherwise there will be a problem. The core code is one sentence, but it needs a lot of code to keep it running, and I can’t watch it anymore.

ShowTime

exports.filter = f= > source => (n, c) = > source(d= > f(d) && n(d), c)
Copy the code

What? One line of code? You read that right! You read that right! You read that right! So let me explain this line of code. Filter is the operator, filter(d=>d>1) means I only accept data greater than 1. This will return source=>… This function accepts a source as the upper-level data source, either as a producer like interval(1000) above, or as another operator. so

const obserable = filter(d= > d > 1)(interval(1000))
Copy the code

You will get a (n,c)=>… You can pass in the next function n and the complete function C to “subscribe”

const disposable = obserable(d= > console.log('get',d),err => console.log('complete'))//err indicates an error
Copy the code

When you subscribe, you get a function called Disposable, which is used to unsubscribe.

disposable()// Unsubscribe
Copy the code

This filter represents the essence of the minimum library: Disposable can be returned all the way from the arrow function. It is implicit in the filter, and the C function representing complete is also directly passed through without any changes. The only thing that needs to be done is the next function, and you need to pass a new next function to the source. Send data to the next function at the next level when the condition is met, otherwise do nothing.

(To be continued)