You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Part 1 - Getting Started/2. Key types.md
+26-18Lines changed: 26 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
1
# Key types
2
2
3
-
Rx is based around two fundamental types, and several others that expand the functionality around them. Those two types are the `Observable` and the `Observer`. we will introduce those, as well as`Subject`s, which ease the learning curve.
3
+
Rx is based around two fundamental types, while several others expand the functionality around the core types. Those two core types are the `Observable` and the `Observer`, which will be introduced in this chapter. We will also introduce`Subject`s, which ease the learning curve.
4
4
5
-
Rx builds upon the [Observer](http://en.wikipedia.org/wiki/Observer_pattern) pattern. It is not unique in doing so. Event handling already exists in Java (e.g. JavaFX's EventHandler). These simpler approaches suffer in comparison to Rx:
5
+
Rx builds upon the [Observer](http://en.wikipedia.org/wiki/Observer_pattern) pattern. It is not unique in doing so. Event handling already exists in Java (e.g. JavaFX's EventHandler). Those are simpler approaches, which suffer in comparison to Rx:
6
6
7
7
* Events through event handlers are hard to compose.
8
8
* They cannot be queried over time
@@ -12,13 +12,13 @@ Rx builds upon the [Observer](http://en.wikipedia.org/wiki/Observer_pattern) pat
12
12
13
13
## Observable
14
14
15
-
[Observable](http://reactivex.io/RxJava/javadoc/rx/Observable) is the first core element that we will see. Since Java does not support extension methods, this class contains a lot of the implementation in Rx. We will be examining it step by step throughout this book. For now, we must understand the`Subscribe` method. Here is one key overload of the method:
15
+
[Observable](http://reactivex.io/RxJava/javadoc/rx/Observable) is the first core element that we will see. This class contains a lot of the implementation of Rx, including all of the core operators. We will be examining it step by step throughout this book. For now, we must understand the `Subscribe` method. Here is one key overload of the method:
16
16
17
17
```java
18
18
publicfinalSubscription subscribe(Subscriber<? super T> subscriber)
19
19
```
20
20
21
-
This is the method that you use to receive the values emitted by the observable. As the values come to be pushed (through policies that we will discuss throughout this book), they are pushed to the subscriber, which is then responsible for the behaviour based on this example. The `Subscriber` here is an implementation of the `Observer`.
21
+
This is the method that you use to receive the values emitted by the observable. As the values come to be pushed (through policies that we will discuss throughout this book), they are pushed to the subscriber, which is then responsible for the behaviour intended by the consumer. The `Subscriber` here is an implementation of the `Observer` interface.
22
22
23
23
An observable pushes 3 kinds of events
24
24
* Values
@@ -28,7 +28,7 @@ An observable pushes 3 kinds of events
28
28
29
29
## Observer
30
30
31
-
We already saw one abstract implementation of the [Observer](http://reactivex.io/RxJava/javadoc/rx/Observer.html), `Subscriber`. `Subscriber` implements some extra functionality and we will see why it is needer later. For now, we should understand the simpler interface.
31
+
We already saw one abstract implementation of the [Observer](http://reactivex.io/RxJava/javadoc/rx/Observer.html), `Subscriber`. `Subscriber` implements some extra functionality and should be used as the basis for our implementations of `Observer`. For now, it is simpler to first understand the interface.
32
32
33
33
```java
34
34
interfaceObserver<T> {
@@ -38,24 +38,24 @@ interface Observer<T> {
38
38
}
39
39
```
40
40
41
-
Those three methods are the behaviour that is executed every time the observable pushes a value. The observer's will have its `onNext` called zero or more times, optionally followed by an `onCompleted` or an `onError`. No calls happen after a call to `onError` or `onCompleted`.
41
+
Those three methods are the behaviour that is executed every time the observable pushes a value. The observer will have its `onNext` called zero or more times, optionally followed by an `onCompleted` or an `onError`. No calls happen after a call to `onError` or `onCompleted`.
42
42
43
-
You'll see a lot of the `Observable`, but not so much of the `Observer`. While it is important to understand the `Observer`, you'll be using a lot of method overloads that hide it.
43
+
When developing Rx code, you'll see a lot of `Observable`, but not so much of `Observer`. While it is important to understand the `Observer`, there are shorthands that that remove the need to instantiate it yourself.
44
44
45
45
46
46
## Implementing Observable and Observer
47
47
48
-
You could manually implement `Observer` or extend `Observable`. In reality that may be unnecessary, since Rx provides all the building blocks you need. It is also dangerous, as interaction between parts of Rx includes conventions and internal plumming that are not obvious. It is both simpler and safer to use the many tools that Rx gives you for generating the functionality that you need.
48
+
You could manually implement `Observer` or extend `Observable`. In reality that will usually be unnecessary, since Rx already provides all the building blocks you need. It is also dangerous, as interaction between parts of Rx includes conventions and internal plumming that are not obvious to a beginner. It is both simpler and safer to use the many tools that Rx gives you for generating the functionality that you need.
49
49
50
-
To subscribe to an observable, it is not necessary to provide instances of Observer at all. There are overloads to `subscribe` that take the functions to be executed for `onNext`, `onError` and `onSubscribe`, hiding the creation of instances. It is not even necessary to provide each of those functions. You can even provide a subset of them, i.e. for`onNext` or for`onNext` and `onError`.
50
+
To subscribe to an observable, it is not necessary to provide instances of `Observer` at all. There are overloads to `subscribe` that simply take the functions to be executed for `onNext`, `onError` and `onSubscribe`, hiding away the instantiation of the corresponding `Observer`. It is not even necessary to provide each of those functions. You can provide a subset of them, i.e. just`onNext` or just`onNext` and `onError`.
51
51
52
-
The introduction of lambda functions in Java 1.8 makes these overload very convenient for our examples.
52
+
The introduction of lambda functions in Java 1.8 makes these overloads very convenient for the short examples that exist in this book.
53
53
54
54
## Subject
55
55
56
-
Subjects are an extension of the `Observable` that also implements the `Observer` interface. The idea may sound odd at first, but they make things a lot simpler in some cases. They can have events pushed to them, which they then push further to their own subscribers. This makes them ideal entry points into Rx code: when you have values coming in from outside of Rx, you can push them into a `Subject`, turning them into an observable. You can think of them as entry points to an Rx pipeline.
56
+
Subjects are an extension of the `Observable` that also implements the `Observer` interface. The idea may sound odd at first, but they make things a lot simpler in some cases. They can have events pushed to them (like observers), which they then push further to their own subscribers (like observables). This makes them ideal entry points into Rx code: when you have values coming in from outside of Rx, you can push them into a `Subject`, turning them into an observable. You can think of them as entry points to an Rx pipeline.
57
57
58
-
`Subject` has two parameter types: the input type and the output type. This is not because `Subject` is the right place transform your values. There are transformation operators to do that, which we will see later.
58
+
`Subject` has two parameter types: the input type and the output type. This was designed so for the sake of abstraction and not because the common uses for subjects involve transforming values. There are transformation operators to do that, which we will see later.
59
59
60
60
There are a few different implementations of `Subject`. We will now examine the most important ones and their differences.
61
61
@@ -82,9 +82,15 @@ Output
82
82
83
83
As we can see in the example, `1` isn't printed because we weren't subscribed when it was pushed. After we subscribed, we began receiving the values that were pushed to the subject.
84
84
85
+
This is the first time we see `subscribe` being used, so it is worth paying attention to how it was used. In this case, we used the overload which expects one [Function](http://reactivex.io/RxJava/javadoc/rx/functions/Function.html) for the case of onNext. That function takes an argument of type `Integer` and returns nothing. Functions without a return type are also called actions. We can provide that function in different ways:
86
+
* we can supply an instance of `Action1<Integer>`,
87
+
* implicitly create one using a [lambda expression](http://en.wikipedia.org/wiki/Anonymous_function#Java) or
88
+
* pass a reference to an existing method that fits the signature.
89
+
In this case, `System.out::println` has an overload that accepts `Object`, so we passed a reference to it. `subscribe` will call `println` with the arriving values as the argument.
90
+
85
91
### ReplaySubject
86
92
87
-
`ReplaySubject` has the special feature of caching all the values pushed to it. When a new subscription is made, the event sequence is replayed from the start for the new subscriber.
93
+
`ReplaySubject` has the special feature of caching all the values pushed to it. When a new subscription is made, the event sequence is replayed from the start for the new subscriber. After catching up, every subscriber receives new events as they come.
88
94
89
95
```java
90
96
ReplaySubject<Integer> s =ReplaySubject.create();
@@ -124,7 +130,7 @@ Late: 2
124
130
Late: 3
125
131
```
126
132
127
-
Our late subscriber now missed the first value, which fell off our buffer of size 2.
133
+
Our late subscriber now missed the first value, which fell off the buffer of size 2. Similarily, old values fall off the buffer as time passes, when the subject is created with `createWithTime`
128
134
129
135
```java
130
136
ReplaySubject<Integer> s =ReplaySubject.createWithTime(150, TimeUnit.MILLISECONDS, Schedulers.immediate());
@@ -148,7 +154,7 @@ Late: 3
148
154
149
155
### BehaviorSubject
150
156
151
-
`BehaviorSubject` only remembers the last value. It is similar to a `ReplaySubject` with a buffer of size 1. An initial value can be provided on creation, therefore guaranteeing that a value will be available immediately on subscription.
157
+
`BehaviorSubject` only remembers the last value. It is similar to a `ReplaySubject` with a buffer of size 1. An initial value can be provided on creation, therefore guaranteeing that a value always will be available immediately on subscription.
152
158
153
159
```java
154
160
BehaviorSubject<Integer> s =BehaviorSubject.create();
@@ -180,7 +186,7 @@ s.subscribe(
180
186
);
181
187
```
182
188
183
-
An initial value is available if anyone subscribes before the first value is pushed
189
+
An initial value is provided to be available if anyone subscribes before the first value is pushed.
184
190
185
191
```java
186
192
BehaviorSubject<Integer> s =BehaviorSubject.create(0);
@@ -198,7 +204,7 @@ Since the defining role of a `BehaviorSubject` is to always have a value readily
198
204
199
205
### AsyncSubject
200
206
201
-
`AsyncSubject` also caches the single last value. The difference now is that it doesn't emit anything until the sequence completes. Its use is to emit a single value and immediately complete.
207
+
`AsyncSubject` also caches the last value. The difference now is that it doesn't emit anything until the sequence completes. Its use is to emit a single value and immediately complete.
202
208
203
209
```java
204
210
AsyncSubject<Integer> s =AsyncSubject.create();
@@ -218,7 +224,7 @@ Note that, if we didn't do `s.onCompleted();`, this example would have printed n
218
224
219
225
## Implicit contracts
220
226
221
-
As we already mentioned, there are contracts in Rx that are not obvious in the code. An important one is that no events are emitted after a termination event (`onError` or `onCompleted`). The implemented subjects respect that:
227
+
As we already mentioned, there are contracts in Rx that are not obvious in the code. An important one is that no events are emitted after a termination event (`onError` or `onCompleted`). The implemented subjects respect that, and the `subscribe` method also prevents some violations of the contract.
222
228
223
229
```java
224
230
Subject<Integer, Integer> s =ReplaySubject.create();
@@ -233,6 +239,8 @@ Output
233
239
0
234
240
```
235
241
242
+
Safety nets like these are not guaranteed in the entirety of the implementation of Rx. It is best that you are mindful not to violate the contract, as this may lead to undefined behaviour.
0 commit comments