Reactive Programming – managing streams and application state

Reactive Programming is all the buzz at the moment. It is similar to the iterator pattern, where you have a collection of values, and iterate over them to obtain these values and make decisions on these values. But these are “pull” paradigms that often result in heavier CPU cycles and memory to hold the entire collection while you are evaluating the concepts.

Reactive Programming uses a concept of an “observable”. Basically this means that whenever you have a value of some sort, whether on its own or part of a collection, you can observe changes to that data value, and have these changes “pushed” to an observer. This is by far way more powerful as it can be done using “stream” based code, where on every value you have an observer function to handle the change, whether it be for a single data value change, or changes to an entire collection (one by one) without the need to hold the collection in memory and take up CPU cycles to iterate.

In effect, it is an event based paradigm on a single value state change. If you have 1000 changes to a value over time, rather than holding onto a collection in memory and iterating over the list, you can respond to each change one at a time, updating any possible dependencies. Whether these dependencies on a value change refer to updating the UI, or restarting a server, each value change triggers the corresponding listener to update the dependencies.

Observable programming is, in effect much more efficient than iterator programming, simply . Similar to promises, it allows for the proper execution of code in a controlled manner on each of these changes, however has an option to allow for any dependency updates to be cancelled based on some very simple function calls that respond to an observed change.

To start at the very beginning, firstly let me explain what an “observable” is.  It is simply an object which holds one or more values, but also holds a “next” function (similar to the next item in a collection using an iterator), an “on success” function (to be fired after the successful completion of an “on next”, and an “on error” function if something goes wrong.  An “observer” function is the one that responds to the “on next”, “on complete”, and “on error” handlers.

It is similar to a promise, but differs in the fact you can cancel any pending operation (since a promise only responds to an “on success”, or “on failure” responder – more specifically, if a promise doesn’t cancel an operation, it also can’t be stopped or discarded when in progress).  It can handle this by first injecting data into a stream, filtering on specific data, and combining with other streams before the actual success handler is invoked.

Using observables are much more efficient (since they are similar to streams, and don’t hold collections), but can also be acted on for particular operations from multiple streams. This is useful for combining streams together, filtering data along the way, and even stopping at events like a “mouseup” before the entire stream is sent to the success handler. This is useful for things that require I/O (like a server or database request, an animation, or calling a render function once the streams have been processed. In essence it is a much better way to handle state changes of your application to ensure things happen when you want them to happen.

For example, and a basic observable pattern, might be to watch for a mouse down, then on a mouse move, call the mouse move handler, and on a mouse up, stop processing all events (even if they are in progress), allowing you to perform final cleanup on a drag operation. Similarly, it can also be used for reading data, where you retrieve the data from one table, filter it against another table, and finally finish the operation only once all data has been retrieved, while still looking at particular records along the way until the operation is finished.

Thinking in streams can be daunting at first, but doesn’t have to be. To work this way does take a different way of thinking, but rather than thinking in sequential patterns (if-then-else), you can change your thinking into (what is the outcome of what I want, what data do I need to get there, and what operations do I need to perform until I get there). At first, a little hard to grasp, but with a little practice means your code will only have to fire when it has to, without holding a large amount of data, and allows you the freedom to write uncomplicated code.  Better yet, it can also be thought of synchronous programming in an asynchronous way to help with debugging.

There are two things you need to be mindful of when using “Reactive Programming”. These are working with changes to state data, and “side effects” of that data. An example of a side effect would be updating a database, or rendering to a screen. These are not to be confused with responding to events in time, mapping, and filtering data to determine when the “on next” handler will be fired, and when you consider a transaction of handlers to be considered “completed”.  A side effect is simply that, a side effect after you have processed your streams.

To distinguish between stream handling and side effects, it is best thought of as “what do I do mid stream using pure functions (eg a computed value of first and last name) vs what do I do with the final stream state (eg update a contact record in a database, or a contact details page on a UI).

To summarise all of this, using Reactive Programming allows you to “react” to mutations, even in an immutable way, and only fire the code you want to fire when you want to fire it. This leads to a ten fold improvement in performance, because you are optimising memory, CPU cycles, and I/O along the way.

Some libraries are available today to help you along. While some of these libraries are very good, they will require you to think differently in your approach but this is well worth your effort in your journey, and will have substantial benefits.  Some useful libraries in this approach are:

Learn how to program using Reactive Programming today. You will be very glad you did.