If you've read or watched any tutorials on reactive programming, then you
probably already know that reactive programming is programming with
asynchronous data streams. But what does that even mean? Here's another way to
think about it. Reactive programming is like taking a series of events that are
happening asynchronously over time, and treating them like a single collection
of objects that you can perform operations on. Think of a standard
collection. We'll use an array of Fibonacci numbers as an example.This
collection is immutable, which means it can't be changed. Let's say we wanted to
grab just the even numbers from this array. One way to do this would be to
filter the collection using LINQ's "where" operator. This would return a completely
new collection leaving the original array untouched. Taking this example a
step further we could chain the "select" operator to transform the values in our
collection. For instance we can multiply each value by two. Again this returns a
completely new collection. The code for this example would look a little
something like this. It's pretty standard stuff if you've ever used LINQ or
worked with collections. A data stream is nothing more than a collection of values,
except for one important distinction: time. The values in a data stream are
emitted asynchronously over time. And because data streams are first-class
citizens, we can pass them around as arguments, return them from functions, and
even assign them to variables. Imagine a data stream of click events. Just like
our previous array example we can filter this stream using the LINQ "where"
operator. And transform the values using the "select" operator.
Then we can subscribe to this feed, passing the emitted values into the
function of our choosing. UniRx provides a long list of operators that can be
used to filter, transform, and combine data streams, making it a powerful tool
for composing asynchronous code. Treating your events like data streams and
thinking in reactive will help you write your code in a more declarative way. But
if you're like me, and you're used to imperative programming, then writing
declarative code isn't the easiest thing to do when you first start out. So let's
take a quick look at an example that will help illustrate the differences
between the two styles. This MonoBehaviour detects double clicks. It does
this by calculating the amount of time that's passed between each click. If it's
under 250 milliseconds then a double click has occurred. The code for this
logic is considered imperative. Imperative code uses statements to
change a program's state. It consists of commands for the computer to perform, and
describes how the program operates. This code contains statements that control
the flow of logic, analyze and update state, and describe what operations
should be executed when. Let's take a look at the same logic using UniRx and
reactive programming. This code makes a declaration. It says, "give me a stream of
data events, but only the ones where the mouse is clicked." Then it says, "collect
groups of all the updates that occur within the same 250 milliseconds, and
give me just the ones that contain more than 2 elements." It then takes the
resulting data stream and subscribes to it.
This is declarative code. Declarative code expresses logic without describing
control flow. It describes what the program needs to accomplish rather than
how to accomplish it. Understanding declarative programming is
a large part of learning how to think reactive. In the next video we'll be
taking a closer look at Observables. Up until now I've been referring to
Observables as "data streams". These are the building blocks that our reactive
programs will create and operate on. If you enjoyed this video, please leave a
like and a comment letting me know what you thought.
For more tutorials like this one, be sure to subscribe with notifications on. And
if you'd like to support the creation of content like this please consider
becoming a patron on the Infallible Code Patreon page.