- Learning RxJava
- Thomas Nield
- 404字
- 2021-07-02 22:22:54
Observable.defer()
Observable.defer() is a powerful factory due to its ability to create a separate state for each Observer. When using certain Observable factories, you may run into some nuances if your source is stateful and you want to create a separate state for each Observer. Your source Observable may not capture something that has changed about its parameters and send emissions that are obsolete. Here is a simple example: we have an Observable.range() built off two static int properties, start and count.
If you subscribe to this Observable, modify the count, and then subscribe again, you will find that the second Observer does not see this change:
import io.reactivex.Observable;
public class Launcher {
private static int start = 1;
private static int count = 5;
public static void main(String[] args) {
Observable<Integer> source = Observable.range(start,count);
source.subscribe(i -> System.out.println("Observer 1: " + i));
//modify count
count = 10;
source.subscribe(i -> System.out.println("Observer 2: " + i));
}
}
The output is as follows:
Observer 1: 1
Observer 1: 2
Observer 1: 3
Observer 1: 4
Observer 1: 5
Observer 2: 1
Observer 2: 2
Observer 2: 3
Observer 2: 4
Observer 2: 5
To remedy this problem of Observable sources not capturing state changes, you can create a fresh Observable for each subscription. This can be achieved using Observable.defer(), which accepts a lambda instructing how to create an Observable for every subscription. Because this creates a new Observable each time, it will reflect any changes driving its parameters:
import io.reactivex.Observable;
public class Launcher {
private static int start = 1;
private static int count = 5;
public static void main(String[] args) {
Observable<Integer> source = Observable.defer(() ->
Observable.range(start,count));
source.subscribe(i -> System.out.println("Observer 1: " + i));
//modify count
count = 10;
source.subscribe(i -> System.out.println("Observer 2: " + i));
}
}
The output is as follows:
Observer 1: 1
Observer 1: 2
Observer 1: 3
Observer 1: 4
Observer 1: 5
Observer 2: 1
Observer 2: 2
Observer 2: 3
Observer 2: 4
Observer 2: 5
Observer 2: 6
Observer 2: 7
Observer 2: 8
Observer 2: 9
Observer 2: 10
That's better! When your Observable source is not capturing changes to the things driving it, try putting it in Observable.defer(). If your Observable source was implemented naively and behaves brokenly with more than one Observer (for example, it reuses an Iterator that only iterates data once), Observable.defer() provides a quick workaround for this as well.
- 手機安全和可信應(yīng)用開發(fā)指南:TrustZone與OP-TEE技術(shù)詳解
- 新編Visual Basic程序設(shè)計上機實驗教程
- 深度實踐OpenStack:基于Python的OpenStack組件開發(fā)
- Java多線程編程實戰(zhàn)指南:設(shè)計模式篇(第2版)
- Java程序設(shè)計(慕課版)
- Kubernetes實戰(zhàn)
- Architecting the Industrial Internet
- Mastering C# Concurrency
- Learning OpenCV 3 Computer Vision with Python(Second Edition)
- AIRIOT物聯(lián)網(wǎng)平臺開發(fā)框架應(yīng)用與實戰(zhàn)
- C++反匯編與逆向分析技術(shù)揭秘(第2版)
- Python爬蟲、數(shù)據(jù)分析與可視化:工具詳解與案例實戰(zhàn)
- Domain-Driven Design in PHP
- Machine Learning for OpenCV
- WCF技術(shù)剖析(卷1)