Reactive Programming - Why choose RxJS?

André Staltz
InstructorAndré Staltz

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 3 years ago

This lesson helps you think in Reactive programming by explaining why it is a beneficial paradigm for programming. See how reactive programming helps you understand the dynamic behavior of a value evolving over time.

[00:01] To help you think in Reactive Programming, we need to understand not just what event streams are, but especially why we should use them. To me, it boils down to one simple reason. It allows you to specify the dynamic behavior of a value completely at the time of creation.

[00:19] We're going to code an example here, but I'm going to write that property down, because it's really important to understand it. Also, it might be better to grasp once it's written down.

[00:38] Let's see the opposite example of this. Let's say you have a variable A, which has initially the value 3. Then you have a variable B, which is 10 * A. If we console log out B, we will see 30.

[00:56] Let's say we change A to be 4. If we console log B, B is still 30. It didn't catch up with this new value of 4, because it's statically declared as 10 * A at the time that this line passed through the flow of control. What we need to do is actually, again, set B to that formula. Now, when we console log B, we see 44. But, if you noticed, I made a type here. Instead of 10, I wrote 11.

[01:35] This means that B, even though it's a value evolving over time, it's not a constant. This declaration here does not specify the dynamic behavior of that value B at the time of declaration, because later I just say it's 11.

[01:54] Ideally, what I would want is I just say that B is always 10 * A, and whenever A changes, then B will be 10 * A's new value.

[02:07] That is what we can accomplish with event streams. Let's say that I have steam A is an event stream of just the value 3. Then I have stream B, which is stream A mapped. Each of these A values will be mapped to 10 * A.

[02:26] If I add an event listener to that stream B and I console log, we will see B being 30.

[02:39] But now I want to change the value of stream A. Here is where a lot of people get stuck, because they want to change stream A. So, they feel like doing this, set to 4, or something like this. But, this is not what we should do. Why?

[03:00] Because A is also a dynamic value over time, and that means that we need to specify that dynamic behavior completely at the time of declaration. This is not the time of declaration. But instead this is the time of declaration, and that's where the trick is.

[03:19] We need to specify not just B's behavior once, but also A's behavior once. We cannot change A later. We have to specify how A will work over time. And we have to specify only at the time of the declaration.

[03:38] If we do this, now we have an event stream that has just simply two events. It has event 3, and then it has event 4, and B will change accordingly whenever A changes. If we run this, we see B being 30 and 40.

[03:54] The why, remember, is because Reactive Programming allows you to specify the dynamic behavior completely only once, at declaration.

Daniel
Daniel
~ 6 years ago

In your example, couldn't you just write b as a function?

var b = function(a) {
  return 10 * a;
}

Problem with the typo solved.

André Staltz
André Staltzinstructor
~ 6 years ago

Hi Daniel. We could, but that has its problems too, watch this presentation to see why: https://www.youtube.com/watch?v=BfZpr0USIi4

Paul Warelis
Paul Warelis
~ 6 years ago

Yeah, I was thinking the same thing. But I think that was a very contrived example Andre used to illustrate the concept

Kostiantyn Hryshyn
Kostiantyn Hryshyn
~ 5 years ago

How can I change the values dynamically? What if I don't know regarding the 4 in the initial state?

var streamA = Rx.Observable.of(3, 4);

André Staltz
André Staltzinstructor
~ 5 years ago

Kostiantyn, all the dynamic updates should be specified in the declaration of the observable. That's the reactive approach. You don't need to know beforehand exactly what values, but you need to know from where will these dynamic values come from. If you want to change the values according to clicks, then you declare the observable with a dependency on the click observable, for example.

Jon
Jon
~ 4 years ago

Hey Andre, hope you have made an "observable" of this thread and are still "subscribed" to new comments :oP

Regards your answer to Kostaintyn above, are you basically saying that the values 'can' change over time but what needs to be specified at declaration only once is the 'type' of construct that is creating the change so that RxJS knows how to treat it?

e.g. Obviously we cant know when a user will click a mouse, so we cant hard code all possible clicks and their values for clientX at declaration... but we can specify where the values should come from (fromEvent). In this way we are fulfilling the comment you wrote in this video and we have "specified the dynamic behaviour of a value at declaration"...its an event emitter! Thats its behaviour!

I cant speak for everyone else... but I know my confusion came from the thought "great, I will learn RxJS and finally turn an array that could change over time into a dynamic stream of data that is subscribed to by various parts of my app, when it changes over time all parts of my app subscribed will know". Since arrays aren't event driven they don't contain any native method of emitting an event to say they have been updated, hence the RxJS "Subject" has to be used to artificially convert them into an event emitter - correct me if I am wrong??

I don't know if you maybe had the same problem when you tried to learn RxJS

Viktor Soroka
Viktor Soroka
~ 4 years ago

There is mental error in code.

 streamB.subscribe(b => console.log(b)) || displayInPreview(b);

The displayInPreview never runs and does not makes sense. Probably that was made after intent to concise the code by using ES2015 arrow functions.