diff --git a/Part 1 - Getting Started/1. Why Rx.md b/Part 1 - Getting Started/1. Why Rx.md index 339ee02..b7874e2 100644 --- a/Part 1 - Getting Started/1. Why Rx.md +++ b/Part 1 - Getting Started/1. Why Rx.md @@ -45,5 +45,5 @@ Those patterns are already well adopted and you may find that introducing Rx on | Previous | Next | | --- | --- | -| | [Key types](/Part 1 - Getting Started/2. Key types.md) | +| | [Key types](/Part%201%20-%20Getting%20Started/2.%20Key%20types.md) | diff --git a/Part 1 - Getting Started/2. Key types.md b/Part 1 - Getting Started/2. Key types.md index 12ac033..7519602 100644 --- a/Part 1 - Getting Started/2. Key types.md +++ b/Part 1 - Getting Started/2. Key types.md @@ -45,7 +45,7 @@ When developing Rx code, you'll see a lot of `Observable`, but not so much of `O ## Implementing Observable and Observer -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. +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 plumbing 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. 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`. @@ -243,4 +243,4 @@ Safety nets like these are not guaranteed in the entirety of the implementation | Previous | Next | | --- | --- | -| [Why Rx](/Part 1 - Getting Started/1. Why Rx.md) | [Lifetime management](/Part 1 - Getting Started/3. Lifetime management.md) | +| [Why Rx](/Part%201%20-%20Getting%20Started/1.%20Why%20Rx.md) | [Lifetime management](/Part%201%20-%20Getting%20Started/3.%20Lifetime%20management.md) | diff --git a/Part 1 - Getting Started/3. Lifetime management.md b/Part 1 - Getting Started/3. Lifetime management.md index c9c03dd..2d1c4fe 100644 --- a/Part 1 - Getting Started/3. Lifetime management.md +++ b/Part 1 - Getting Started/3. Lifetime management.md @@ -151,4 +151,4 @@ We will see more of them later in this book. It is interesting to note that `Sub | Previous | Next | | --- | --- | -| [Key types](/Part 1 - Getting Started/2. Key types.md) | [Chapter 2](/Part 2 - Sequence Basics/1. Creating a sequence.md) | +| [Key types](/Part%201%20-%20Getting%20Started/2.%20Key%20types.md) | [Chapter 2](/Part%202%20-%20Sequence%20Basics/1.%20Creating%20a%20sequence.md) | diff --git a/Part 2 - Sequence Basics/1. Creating a sequence.md b/Part 2 - Sequence Basics/1. Creating a sequence.md index 3b54222..a71693e 100644 --- a/Part 2 - Sequence Basics/1. Creating a sequence.md +++ b/Part 2 - Sequence Basics/1. Creating a sequence.md @@ -246,7 +246,7 @@ Depending on what the event is, the event type (here `ActionEvent`) may be meani Much like most of the functions we've seen so far, you can turn any kind of input into an Rx observable with `create`. There are several shorthands for converting common types of input. -`Future`s are part of the Java framework and you may come across them while using frameworks that use concurrency. They are a less powerful concept for concurrency than Rx, since they only return one value. Naturally, you'd like to them into observables. +`Future`s are part of the Java framework and you may come across them while using frameworks that use concurrency. They are a less powerful concept for concurrency than Rx, since they only return one value. Naturally, you may like to turn them into observables. ```java FutureTask f = new FutureTask(() -> { @@ -302,4 +302,4 @@ Completed | Previous | Next | | --- | --- | -| [Lifetime management](/Part 1 - Getting Started/3. Lifetime management.md) | [Reducing a sequence](/Part 2 - Sequence Basics/2. Reducing a sequence.md) | +| [Lifetime management](/Part%201%20-%20Getting%20Started/3.%20Lifetime%20management.md) | [Reducing a sequence](/Part%202%20-%20Sequence%20Basics/2.%20Reducing%20a%20sequence.md) | diff --git a/Part 2 - Sequence Basics/2. Reducing a sequence.md b/Part 2 - Sequence Basics/2. Reducing a sequence.md index 508fa9f..e22c0b0 100644 --- a/Part 2 - Sequence Basics/2. Reducing a sequence.md +++ b/Part 2 - Sequence Basics/2. Reducing a sequence.md @@ -441,4 +441,4 @@ Subscription subscription = values | Previous | Next | | --- | --- | -| [Creating a sequence](/Part 2 - Sequence Basics/1. Creating a sequence.md) | [Inspection](/Part 2 - Sequence Basics/3. Inspection.md) | +| [Creating a sequence](/Part%202%20-%20Sequence%20Basics/1.%20Creating%20a%20sequence.md) | [Inspection](/Part%202%20-%20Sequence%20Basics/3.%20Inspection.md) | diff --git a/Part 2 - Sequence Basics/3. Inspection.md b/Part 2 - Sequence Basics/3. Inspection.md index 893edf6..3f95a2a 100644 --- a/Part 2 - Sequence Basics/3. Inspection.md +++ b/Part 2 - Sequence Basics/3. Inspection.md @@ -338,4 +338,5 @@ Error: java.lang.Exception | Previous | Next | | --- | --- | -| [Reducing a sequence](/Part 2 - Sequence Basics/2. Reducing a sequence.md) | [Aggregation](/Part 2 - Sequence Basics/4. Aggregation.md) | +| [Reducing a sequence](/Part%202%20-%20Sequence%20Basics/2.%20Reducing%20a%20sequence.md) | [Aggregation](/Part%202%20-%20Sequence%20Basics/4.%20Aggregation.md) | + diff --git a/Part 2 - Sequence Basics/4. Aggregation.md b/Part 2 - Sequence Basics/4. Aggregation.md index 7687cfc..081324f 100644 --- a/Part 2 - Sequence Basics/4. Aggregation.md +++ b/Part 2 - Sequence Basics/4. Aggregation.md @@ -567,4 +567,4 @@ Nesting observables to consume them doesn't make much sense. Towards the end of | Previous | Next | | --- | --- | -| [Inspection](/Part 2 - Sequence Basics/3. Inspection.md) | [Transformation of sequences](/Part 2 - Sequence Basics/5. Transformation of sequences.md) | +| [Inspection](/Part%202%20-%20Sequence%20Basics/3.%20Inspection.md) | [Transformation of sequences](/Part%202%20-%20Sequence%20Basics/5.%20Transformation%20of%20sequences.md) | diff --git a/Part 2 - Sequence Basics/5. Transformation of sequences.md b/Part 2 - Sequence Basics/5. Transformation of sequences.md index fdc54c8..95bccd8 100644 --- a/Part 2 - Sequence Basics/5. Transformation of sequences.md +++ b/Part 2 - Sequence Basics/5. Transformation of sequences.md @@ -487,4 +487,4 @@ Observable.range(1, 3) | Previous | Next | | --- | --- | -| [Aggregation](/Part 2 - Sequence Basics/4. Aggregation.md) | [Chapter 3 - Taming the sequence](/Part 3 - Taming the sequence/1. Side effects.md) | +| [Aggregation](/Part%202%20-%20Sequence%20Basics/4.%20Aggregation.md) | [Chapter 3 - Taming the sequence](/Part%203%20-%20Taming%20the%20sequence/1.%20Side%20effects.md) | diff --git a/Part 3 - Taming the sequence/1. Side effects.md b/Part 3 - Taming the sequence/1. Side effects.md index 81be09f..a4bcdeb 100644 --- a/Part 3 - Taming the sequence/1. Side effects.md +++ b/Part 3 - Taming the sequence/1. Side effects.md @@ -329,4 +329,4 @@ The first subscriber is the first to be called for each item. Its action is to m | Previous | Next | | --- | --- | -| [Transformation of sequences](/Part 2 - Sequence Basics/5. Transformation of sequences.md) | [Leaving the monad](/Part 3 - Taming the sequence/2. Leaving the monad.md) | +| [Transformation of sequences](/Part%202%20-%20Sequence%20Basics/5.%20Transformation%20of%20sequences.md) | [Leaving the monad](/Part%203%20-%20Taming%20the%20sequence/2.%20Leaving%20the%20monad.md) | diff --git a/Part 3 - Taming the sequence/2. Leaving the monad.md b/Part 3 - Taming the sequence/2. Leaving the monad.md index ff12ac9..78746ce 100644 --- a/Part 3 - Taming the sequence/2. Leaving the monad.md +++ b/Part 3 - Taming the sequence/2. Leaving the monad.md @@ -325,4 +325,4 @@ Some blocking ways to access observables, such as `last()`, require the observab | Previous | Next | | --- | --- | -| [Side effects](/Part 3 - Taming the sequence/1. Side effects.md) | [Advanced error handling](/Part 3 - Taming the sequence/3. Advanced error handling.md) | +| [Side effects](/Part%203%20-%20Taming%20the%20sequence/1.%20Side%20effects.md) | [Advanced error handling](/Part%203%20-%20Taming%20the%20sequence/3.%20Advanced%20error%20handling.md) | diff --git a/Part 3 - Taming the sequence/3. Advanced error handling.md b/Part 3 - Taming the sequence/3. Advanced error handling.md index 2fc76f4..1688ccc 100644 --- a/Part 3 - Taming the sequence/3. Advanced error handling.md +++ b/Part 3 - Taming the sequence/3. Advanced error handling.md @@ -234,4 +234,4 @@ It is important to note here that we are responsible for terminating the observa | Previous | Next | | --- | --- | -| [Leaving the monad](/Part 3 - Taming the sequence/2. Leaving the monad.md) | [Combining sequences](/Part 3 - Taming the sequence/4. Combining sequences.md) | +| [Leaving the monad](/Part%203%20-%20Taming%20the%20sequence/2.%20Leaving%20the%20monad.md) | [Combining sequences](/Part%203%20-%20Taming%20the%20sequence/4.%20Combining%20sequences.md) | diff --git a/Part 3 - Taming the sequence/4. Combining sequences.md b/Part 3 - Taming the sequence/4. Combining sequences.md index fa3ea6d..17b6eae 100644 --- a/Part 3 - Taming the sequence/4. Combining sequences.md +++ b/Part 3 - Taming the sequence/4. Combining sequences.md @@ -673,4 +673,4 @@ I like to think of `combineLatest` as one event occuring in the context of anoth | Previous | Next | | --- | --- | -| [Advanced error handling](/Part 3 - Taming the sequence/3. Advanced error handling.md) | [Time-shifted sequences](/Part 3 - Taming the sequence/5. Time-shifted sequences.md) | +| [Advanced error handling](/Part%203%20-%20Taming%20the%20sequence/3.%20Advanced%20error%20handling.md) | [Time-shifted sequences](/Part%203%20-%20Taming%20the%20sequence/5.%20Time-shifted%20sequences.md) | diff --git a/Part 3 - Taming the sequence/5. Time-shifted sequences.md b/Part 3 - Taming the sequence/5. Time-shifted sequences.md index abb50bc..2a1c565 100644 --- a/Part 3 - Taming the sequence/5. Time-shifted sequences.md +++ b/Part 3 - Taming the sequence/5. Time-shifted sequences.md @@ -81,7 +81,7 @@ We see a lot of empty lists here. This is because the buffer is emitted both whe #### buffer with signal -Instead of fixed points in time, you can also signal `buffer` with an observable to flush. Every time the signal emits onNext, the values in the buffer will be emitted will be emitted. Buffering with a signal can be very useful if you want to buffer values until the moment that you are ready for them. +Instead of fixed points in time, you can also signal `buffer` with an observable to flush. Every time the signal emits onNext, the values in the buffer will be emitted. Buffering with a signal can be very useful if you want to buffer values until the moment that you are ready for them. ![](https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/buffer8.png) @@ -155,7 +155,7 @@ Observable.interval(100, TimeUnit.MILLISECONDS).take(10) #### buffer by signal -The last and most powerful variant or `buffer` allows you to define the start and the end of buffers using signaling observables. +The last and most powerful variant of `buffer` allows you to define the start and the end of buffers using signaling observables. ```java public final Observable> buffer( Observable bufferOpenings, @@ -368,7 +368,7 @@ Observable.interval(150, TimeUnit.MILLISECONDS) ## Throttling -Throttling is also intended for thining out a sequence. When the producer emits more values than we want and we don't need every sequential value, we can thin out the sequence by throttling it. +Throttling is also intended for thinning out a sequence. When the producer emits more values than we want and we don't need every sequential value, we can thin out the sequence by throttling it. ### throttleFirst @@ -603,4 +603,4 @@ The output is the same as the previous two examples | Previous | Next | | --- | --- | -| [Combining sequences](/Part 3 - Taming the sequence/4. Combining sequences.md) | [Hot and cold observables](/Part 3 - Taming the sequence/6. Hot and Cold observables.md) | +| [Combining sequences](/Part%203%20-%20Taming%20the%20sequence/4.%20Combining%20sequences.md) | [Hot and cold observables](/Part%203%20-%20Taming%20the%20sequence/6.%20Hot%20and%20Cold%20observables.md) | diff --git a/Part 3 - Taming the sequence/6. Hot and Cold observables.md b/Part 3 - Taming the sequence/6. Hot and Cold observables.md index 0800734..4f87b03 100644 --- a/Part 3 - Taming the sequence/6. Hot and Cold observables.md +++ b/Part 3 - Taming the sequence/6. Hot and Cold observables.md @@ -364,4 +364,4 @@ The `share` method is an alias for `Observable.publish().refCount()`. It allows | Previous | Next | | --- | --- | -| [Time-shifted sequences](/Part 3 - Taming the sequence/5. Time-shifted sequences.md) | [Custom operators](/Part 3 - Taming the sequence/7. Custom operators.md) | +| [Time-shifted sequences](/Part%203%20-%20Taming%20the%20sequence/5.%20Time-shifted%20sequences.md) | [Custom operators](/Part%203%20-%20Taming%20the%20sequence/7.%20Custom%20operators.md) | diff --git a/Part 3 - Taming the sequence/7. Custom operators.md b/Part 3 - Taming the sequence/7. Custom operators.md index 30f3f2e..5123a19 100644 --- a/Part 3 - Taming the sequence/7. Custom operators.md +++ b/Part 3 - Taming the sequence/7. Custom operators.md @@ -404,4 +404,4 @@ Theoretically, any operator can be implemented as both `Observable.Operator` and | Previous | Next | | --- | --- | -| [Hot and cold observables](/Part 3 - Taming the sequence/6. Hot and Cold observables.md) | [Chapter 4 - Concurrency](/Part 4 - Concurrency/1. Scheduling and threading.md) | +| [Hot and cold observables](/Part%203%20-%20Taming%20the%20sequence/6.%20Hot%20and%20Cold%20observables.md) | [Chapter 4 - Concurrency](/Part%204%20-%20Concurrency/1.%20Scheduling%20and%20threading.md) | diff --git a/Part 4 - Concurrency/1. Scheduling and threading.md b/Part 4 - Concurrency/1. Scheduling and threading.md index f5f1dc9..c011a5f 100644 --- a/Part 4 - Concurrency/1. Scheduling and threading.md +++ b/Part 4 - Concurrency/1. Scheduling and threading.md @@ -392,4 +392,4 @@ Again on 11 | Previous | Next | | --- | --- | -| [Custom operators](/Part 3 - Taming the sequence/7. Custom operators.md) | [Testing Rx](/Part 4 - Concurrency/2. Testing Rx.md) | +| [Custom operators](/Part%203%20-%20Taming%20the%20sequence/7.%20Custom%20operators.md) | [Testing Rx](/Part%204%20-%20Concurrency/2.%20Testing%20Rx.md) | diff --git a/Part 4 - Concurrency/2. Testing Rx.md b/Part 4 - Concurrency/2. Testing Rx.md index 468ca43..2849840 100644 --- a/Part 4 - Concurrency/2. Testing Rx.md +++ b/Part 4 - Concurrency/2. Testing Rx.md @@ -227,4 +227,4 @@ Awaiting with a timeout will cause an exception if the observable fails to compl | Previous | Next | | --- | --- | -| [Scheduling and threading](/Part 4 - Concurrency/1. Scheduling and threading.md) | [Sequences of coincidence](/Part 4 - Concurrency/3. Sequences of coincidence.md) | +| [Scheduling and threading](/Part%204%20-%20Concurrency/1.%20Scheduling%20and%20threading.md) | [Sequences of coincidence](/Part%204%20-%20Concurrency/3.%20Sequences%20of%20coincidence.md) | diff --git a/Part 4 - Concurrency/3. Sequences of coincidence.md b/Part 4 - Concurrency/3. Sequences of coincidence.md index c04bcda..aace31f 100644 --- a/Part 4 - Concurrency/3. Sequences of coincidence.md +++ b/Part 4 - Concurrency/3. Sequences of coincidence.md @@ -293,4 +293,4 @@ You can also implement `groupJoin` with `join` and `groupBy`. Doing so would req | Previous | Next | | --- | --- | -| [Testing Rx](/Part 4 - Concurrency/2. Testing Rx.md) | [Backpressure](/Part 4 - Concurrency/4. Backpressure.md) | +| [Testing Rx](/Part%204%20-%20Concurrency/2.%20Testing%20Rx.md) | [Backpressure](/Part%204%20-%20Concurrency/4.%20Backpressure.md) | diff --git a/Part 4 - Concurrency/4. Backpressure.md b/Part 4 - Concurrency/4. Backpressure.md index f239ff7..395477c 100644 --- a/Part 4 - Concurrency/4. Backpressure.md +++ b/Part 4 - Concurrency/4. Backpressure.md @@ -22,7 +22,7 @@ Here, the producer has its values ready and can emit them with no delay. The con This works like that only for synchronous execution. It is very common for the producer and the consumer to be asynchronous. So, what happens when a producer and a consumer operate asynchronously at different speeds? -Let's first consider the traditional pull-based model, such as an iterator. In a pull-based model, the consumer requests the values. If the producer is slower, the consumer will block on request and resume when the next value arrives. If the procuder is faster, then the producer will have idle time waiting for the consumer to request the next value. +Let's first consider the traditional pull-based model, such as an iterator. In a pull-based model, the consumer requests the values. If the producer is slower, the consumer will block on request and resume when the next value arrives. If the producer is faster, then the producer will have idle time waiting for the consumer to request the next value. Rx push-based, not pull-based. In Rx, it is the producer that pushes values to the consumer when the values are ready. If the producer is slower, then the consumer will have idle time waiting for the next value to arrive. If the producer is faster, without any provisions, it will keep force-feeding data to consumer without ever knowing about the consumer's difficulties. @@ -78,7 +78,7 @@ Observable.interval(1, TimeUnit.MILLISECONDS) ``` The are similar operators that can serve the same purpose. -* The [throttle](/Part 3 - Taming the sequence/5. Time-shifted sequences.md#throttling) family of operators also filters on rate, but allows you to speficy in a diffent way which element to let through when stressed. +* The [throttle](/Part 3 - Taming the sequence/5. Time-shifted sequences.md#throttling) family of operators also filters on rate, but allows you to specify in a different way which element to let through when stressed. * [Debounce](/Part 3 - Taming the sequence/5. Time-shifted sequences.md#debouncing) does not cut the rate to a fixed maximum. Instead, it will completely remove every burst of information and replace it with a single value. #### Collect @@ -266,7 +266,7 @@ Requested 90 Requested 90 ``` -The `zip` operator starts by requesting enough items to fill its buffer, and requests more when it consumes them. The details of how many items `zip` requests isn't interesting. What the reader should take away is the realisation that some buffering and backpressure exist in Rx whether the developer requests for it or not. This gives an Rx pipeline some flexibility, where you might expect none. It might trick you into thinking that your code is solid, by silently saving small tests from failing, but you're not safe until you have explicitly declared behaviour with regard to backpressure. +The `zip` operator starts by requesting enough items to fill its buffer, and requests more when it consumes them. The details of how many items `zip` requests isn't interesting. What the reader should take away is the realization that some buffering and backpressure exist in Rx whether the developer requests for it or not. This gives an Rx pipeline some flexibility, where you might expect none. It might trick you into thinking that your code is solid, by silently saving small tests from failing, but you're not safe until you have explicitly declared behaviour with regard to backpressure. ## Backpressure policies @@ -348,9 +348,9 @@ Observable.interval(1, TimeUnit.MILLISECONDS) ... ``` -What we see here is that the first 128 items where consumed normally, but then we jumped forward. The items inbetween were dropped by `onBackPressureDrop`. Even though we did not request it, the first 128 items were still buffered, since `observeOn` uses a small buffer between switching threads. +What we see here is that the first 128 items where consumed normally, but then we jumped forward. The items in-between were dropped by `onBackPressureDrop`. Even though we did not request it, the first 128 items were still buffered, since `observeOn` uses a small buffer between switching threads. | Previous | Next | | --- | --- | -| [Sequences of coincidence](/Part 4 - Concurrency/3. Sequences of coincidence.md) | | +| [Sequences of coincidence](/Part%204%20-%20Concurrency/3.%20Sequences%20of%20coincidence.md) | | diff --git a/README.md b/README.md index 04a8584..eadd1b8 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This guide aims to introduce a beginner reactive programmer to the complete powe No experience with either reactive or functional programming is needed to follow the book. Familiarity with the basics of Java is required. -[Begin learning](/Part 1 - Getting Started/1. Why Rx.md) +[Begin learning](/Part%201%20-%20Getting%20Started/1.%20Why%20Rx.md) ### Structure