One programming paradigm that we haven't talked about so far but that Angular heavily relies on/encourages is called Reactive Programming (RP) or, more specifically, Functional Reactive Programming (FRP).
RP is not new at all; its principles have been described and studied since the early 1970s. RP and FRP have gained a lot of traction in recent years thanks to the rise of microservice-based architectures and the decline of Moore's law (https://www.scientificamerican.com/article/end-of-moores-law-its-not-just-about-physics). With the now much slower yearly increase in raw CPU power, the alternative is to develop systems that can take advantage of more CPUs or CPU cores through parallelism and workload distribution.
The RP paradigm is based on the idea that, most of the time, we can treat/manipulate inputs and outputs as streams of events/data. Simply put, we can treat most inputs and outputs as asynchronous data streams and perform stream processing in a non-blocking fashion.
A famous design pattern that RP is related to is called the observer pattern. That design pattern is useful when the state of a subject is of interest to outside parties called observers. The observers can subscribe to a subject and be notified whenever an event occurs. There are observable elements (that is, subjects) and observers.
With RP, we subscribe to streams and use a declarative approach to define what to do when new data arrives or when events occur. This approach is powerful because it means that, at runtime, the processing itself can be performed in a non-blocking way, potentially on different threads or CPU cores.
RP, therefore, embraces an event-driven approach through which we can react to events pushed into a stream that we are observing. Using RP, we can, of course, also define and publish our own streams and events and use those to create virtual pipes between different parts of our applications.
Event-driven architectures put a lot of emphasis on observing or reacting to changes in streams of events. For instance, if you write an application for the stock market, you might be interested in observing the stream of values corresponding to all changes in valuation for specific stocks. Using RP, you can then describe what should be done when events are received. For example, you could instruct your program to sell when prices go below a certain threshold in order to cut losses, and much more.
If you think about it, events are omnipresent in web browsers—literally, thousands of events are generated each second when the following happen:
- You move your mouse.
- You click on elements on the page.
- You touch the screen.
- The browser receives a response to an HTTP call.
- The DOM is modified.
- The browser window is resized.
- You zoom in or out.
- You type something.
- You go online or offline.
The examples are countless! In addition, most of these events are asynchronous in nature. If you are interested in specific events, then you declare callback functions that will be invoked when those events occur.
But what if we could subscribe to a stream of mouse click events? Or to a stream of DOM modification events? Or even to a stream of application-specific events (for example, when a new comment has just been added on a screen)?
Well, thanks to RP libraries, we can do exactly that and much more!