Hello folks,
If you are a programmer, the chances are high that you have come across the phrase 'reactive programming'. And also the chances are high that you have used it a lot but still, you do not understand it fully. Today, in this article of the series Reactive programming in JavaScript, we will start by understanding the core concepts of reactive programming and then will build the mental model around the concept. I will also attempt to help you to understand the reactive approach to programming using real-world examples.
Understanding the keyword of "Reactive"
Before we jump into understanding reactive programming, let's try to simplify the keyword "reactive". Imagine a real-world scenario of producer and consumer. You are looking to purchase a new mobile phone of a specific brand. You visit an e-commerce website that sells such phones, but it is currently out of stock. You visit the next day and you get to know the same. As there is no information on when the phone is available, it is not going to be an effective way to keep checking for the phone on the website every now and then. Instead, you opt for the notification via email service from the website to alert you once the phone becomes available. Now as soon as the cell phone becomes available on their website, you are notified via email.
Here the producer is the e-commerce website and you are the consumer. When the phone becomes available, the producer sends you an event (mail notification) to which the consumer reacts (you immediately try to place the order). The producer need not be aware of what the consumer performs after being notified. You may or may not place the order which is up to you. In nutshell, "reactive" is nothing but reacting to an event or change.
What is Reactive Programming?
Similar to the real-world examples, in programming also, we come across a lot of scenarios where we need to react to some event. We might have written a lot of programs in which we need to perform some action when something completes. Let's try to take a simple example of a signup page. We can see a password field in almost any of the signup pages. When the user starts typing characters, the validation for the password happens. If the password length is less than 8 characters (the password field should have a minimum of 8 characters on that website), the user will not be allowed to proceed with the signup process.
Here the producer (user) is producing the events (which occurs on each keystroke) and the consumer (password validation functionality) performs its actions. By looking at the examples given above, reactive programming can be a programming paradigm in which the code or functionality reacts to some incoming data or event.
Lets try to visualize
Here we will try to visualize the reactivity using a simple example of browser events. When some event occurs such as 'click', browser API provides the developer a notification on the same. This is done by registering/subscribing using a callback function for a specific event.
For a button present on our webpage "CLICK ME", we can add a 'click' event handler function called 'clickHandler' as a callback. What it means is that for every click of the button, the callback function will be triggered. For every click event produced by the button, we can react inside the callback function which in our case is the clickHandler.
The actual code looks something like below
function clickHandler(event){
console.log("Button is clicked");
// perform some action
}
element.addEventListener('click', clickHandler);
Yes. It is already known to you. Nothing new is happening. As we discussed earlier in the producer-consumer example, what happens inside the clickHandler function is neither the responsibility of the button click event nor its concern. Both can work in isolation without knowing about each other's functionalities. Yes, kind of a pub-sub model.
Let's try to cover a few more additional cases.
It can happen that, the user is no more interested in buying that phone. In such a case, the user may not react at all to the email notification or might unsubscribe from the service.
Similarly, once the clickHandler function is no longer wishes to listen to the events, it can unsubscribe. After subscription, clickHandler will not get any events or get triggered even if the button is clicked. (same as the user, who will not get a notification after unsubscribing even though mobile becomes available on the website in the future)
The actual code looks something like below
element.removeEventListener('click', clickHandler);
There could be a scenario where more than one user wishes to buy the same phone and have subscribed to the notification.
And what about the multiple events? The phone might become available for some time and before the customer buys, may get out of stock. After a few days again the notification might come once the mobile phone becomes in stock.
In our case, the user might click the button not once; but multiple times. Multiple events will be created and the clickHandler will react that many times. Fairly straightforward to understand.
Reactive programming in practice
As we have understood what does reactive in programming means, let's try to apply this programming model and understand the design of the components in a small system.
Below shown are the two components of an e-commerce web application; Cart and Invoice.
In the above diagram of the components, you can see when an item is added or removed in the cart, that component modifies the dependent component i.e invoice component. Invoice is dependent on cart items as the amount calculated in the invoice is the sum of the prices of the items present inside the cart.
If you look at the arrow it starts from the cart component. Here the cart is the driver and it calls the functionality of the dependent component on any modification to itself.
Unlike before, in this component diagram cart is not the driver for its dependent components. Cart component is doing the work of its modification on item addition or removal and sends an event for other components to know, that cart is modified. The invoice component is dependent on the cart component, which is subscribed to that event and modifies itself when such an event occurs.
If you look at the arrow it ends at the Invoice component. Here the invoice is reactive and performs its functionality when the cart gets modified. The cart component is unaware that the invoice component is dependent on it.
Is that all?
As we have already seen, reactive programming is not about syntax or rules. It is about the flow of data and a way of writing the program. Reactive programming is a paradigm. You react (perform actions) when events/data flow in. You are not concerned about how and from where the data flows. You are concerned about listening to such incoming data and performing your actions (reactions). You choose whether to listen to the data or not as per your needs. Also, you stop listening to the data when you are not interested.
Yes. That's all we need, to get started with reactive programming. We have just learned the fundamentals of reactive programming and this helps us to build our mental model around it. Now that you have understood the fundamental concept of reactive programming, in the next article Reactivity in JavaScript, we will see reactive programming in action.