preface

What is FRP?

Functional Reactive Programming (Reactive Programming)

For functional programming, we are not unfamiliar, in my JS column can find a lot of related articles ~~

Here’s a quick review of functional programming features:

  1. The function is a first-class citizen(This means that functions can be assigned to variables or stored in data structures, or used as arguments or return values of other functions.)
  2. Higher-order functions(A function that takes a function as an argument or returns a function)
  3. There are no implicit inputs and outputs(Input is passed as a function input parameter and output is returned as a function return)
  4. Invariant of values(When the state of the program changes, instead of directly modifying the current data, a new data is created and traced)
  5. Declarative programming style, not imperative(Focus on the “what,” not the “what.”)

Here’s a simple example in code:

Int factorial1(int x) {int result = 1; for (int i = 1; i <= x; i ++) { result *= i; } return result; Int factorial2(int x) {if (x == 1) return 1; return x * factorial2(x - 1); }Copy the code

The above code is used to implement the factorial calculation. Instruction programming, thinking like a machine with instructions that tell the computer what to do about a problem.

In functional programming, the idea is to think mathematically. The mathematical expression of factorial is: f(n) = n*f(n-1) (n > 1), f(n) = 1 (n = 1), using recursion to solve the problem. There is basically no amount of state, just expressions and no assignment statements.

OK, having said that, I have a general review of functional programming, and now I will introduce today’s protagonist — functional responsive programming

The body of the

What is a “response”?

You must be familiar with!

In short: when the data changes, it automatically triggers to tell us that it has changed

Isn’t that what vue.js is all about? Vue2 collects data changes (dependent collection) through getter/setter of definedProperty;

When developing with VUE, data and graphics change as soon as bound data changes, and developers don’t need to write code about how to notify changes. They just need to focus on what to do when changes happen. This is typically Reactive Programming.

So, you can roughly guess: functional responsive programming = functional + responsive programming

In fact, it does

A picture is worth a thousand words:

Programming Paradigm diagram (part)

As shown in the figure, there are two families of declarative programming, namely functional programming and data flow programming. Data flow programming derived from responsive programming; Functional responsive programming inherits both functional and responsive programming (each with its own advantages);

  • Reactive programming can change the binding processing of event sources (time-varying data inputs) at run time, but the organization of data flow programming is determined from the outset.

Flow of events

Functional responsive programming (FRP) can process the flow of events more efficiently without managing state.

For example, 🌰

var a = function (b,c) {

    return b + c 

} // a = b + c
Copy the code

Where A actually represents the sum of B and C, if B or C is constantly changing, how can the value of A be triggered to change as well?

That is, the above code is just an expression and does not specify that the value of A depends on B and C.

Reactive can be used to bind relationships between values:

 //A = B + C
    var reactiveA = $R(function (b, c) { return b + c });
    var reactiveB = $R.state(2);
    var reactiveC = $R.state(1);
    reactiveA.bindTo(reactiveB, reactiveC);

    reactiveA();   //-> 3
    reactiveB(5);  //Set reactiveB to 5
    reactiveC(10); //Set reactiveC to 10
    reactiveA();   //-> 15
<p>
Copy the code

B and C can be regarded as the observed, while A acts as the observer. As time goes by, the values of B and C keep changing, and this change will be transmitted to A;

What functional responsive programming (FRP) does is: iterate through the whole set of things flow, play back the things that caused changes in B and C, and get the result of A;

Event streams are called Observable sequences, which are Monads.

  • Note: Since it is a Monads, it means that there is delayed calculation, that is, only when the variable is actually used, the whole chain traversal process is the same. More and more

RxJS

In JS, RxJS is the third party framework that can embody FRP. With RxJS, we can get a feel for what functional responsive programming looks like:

In native JavaScript

var handler = (e) => { console.log(e); document.body.removeEventListener('click', handler); / / end listen} / / registered to monitor the document body. The addEventListener (" click ", handler);Copy the code

In RXJS:

Rx.observable. fromEvent(document.body, 'click') // Register listener. Take (1) // subscribe(console.log);Copy the code
  • RxJS is a LIBRARY of Observable Sequences that combine asynchronous behavior and event bases. You can think of RxJS as Lodash for asynchronous behavior.

Drag and drop of actual combat

To demonstrate a combat chestnut 🌰 :

Implement a simple drag-and-drop function;

Drag and drop function, can be understood as: to observe mousedown, Mousemove, mouseup and other events, and change the position of the small box accordingly.

First, to analyze, in order to move the cubes accordingly, we need to know:

1). The initial position of the small box when it is dragged;

2). The small box needs to move to a new position when it is dragged and moved.

The data flow is as follows:

mousedown   : --d----------------------d---------
mousemove   : -m--m-m-m--m--m---m-m-------m-m-m--
mouseup     : ---------u---------------------u---

dragUpdate  : ----m-m-m-------------------m-m----
Copy the code

Every time mousemove is triggered between mousedown and Mouseup, the position of the cube is updated.

// Pseudo-code (core) mousedown.switchMap(() => mousemove.takeUntil(mouseup))Copy the code
Const box = document.getelementById ('box') const mouseDown$= rx.Observable. FromEvent (box, 'mousedown') const mouseMove$ = Rx.Observable.fromEvent(document, 'mousemove') const mouseUp$ = Rx.Observable.fromEvent(document, 'mouseup') mouseDown$.map((event) => ({ pos: getTranslate(box), event, })) .switchMap((initialState) => { const initialPos = initialState.pos const { clientX, clientY } = initialState.event return mouseMove$.map((moveEvent) => ({ x: moveEvent.clientX - clientX + initialPos.x, y: moveEvent.clientY - clientY + initialPos.y, })) .takeUntil(mouseUp$) }) .subscribe((pos) => { setTranslate(box, Pos) // The main function of getTranslate and setTranslate is to get and update the position of the box})Copy the code

Codepen experience address

If you are writing with the common imperative style JS natively:

window.onload = function() { var dragCircle = document.getElementById('dragCircle'); / / get the mouse to click when the relative position in the div. DragCircle onmousedown = function (ev) {var ev = ev | | window. The event; var relaX = ev.clientX - this.offsetLeft; var relaY = ev.clientY - this.offsetTop; / / get the current mouse position, minus the div and the relative position of the current div should be the position of the drag and drop the document. The onmousemove = function (ev) {var ev = ev | | window. The event; dragCircle.style.left = ev.clientX - relaX + 'px'; dragCircle.style.top = ev.clientY - relaY + 'px'; }; document.onmouseup = function(ev) { var ev = ev || window.event; document.onmousemove = null; document.onmouseup = null; }}}Copy the code

Codepen experience address

The way you listen to the flow of events is more consistent with the usual understanding of how things change, and the code is organized more cleanly and extensible.

summary

OK, through this article, we understand functional programming, responsive programming, functional responsive programming basic concepts, characteristics, and the relationship between them; Also with the help of RxJS to understand the functional responsive programming code implementation;

More on RxJS to come

If you feel good, why not click 👍

I’m Nuggets Anthony, output exposure input, technical insight into life, goodbye ~~

Reference:

  • Mastering RxJS in 30 Days (01) : Get to know RxJS
  • Functional Responsive Programming (FRP) from Getting Started to “Giving up”
  • What is functional responsive programming
  • RxJS Chinese document
  • Drag and drop
  • Advantages Rxjs brings to applications