官术网_书友最值得收藏!

Hot Observables

You just learned about the cold Observable, which works much like a music CD. A hot Observable is more like a radio station. It broadcasts the same emissions to all Observers at the same time. If an Observer subscribes to a hot Observable, receives some emissions, and then another Observer comes in afterwards, that second Observer will have missed those emissions. Just like a radio station, if you tune in too late, you will have missed that song.

Logically, hot Observables often represent events rather than finite datasets. The events can carry data with them, but there is a time-sensitive component where late observers can miss previously emitted data.

For instance, a JavaFX or Android UI event can be represented as a hot Observable. In JavaFX, you can create an Observable<Boolean> off a selectedProperty() operator of a  ToggleButton using Observable.create(). You can then transform the Boolean emissions into strings indicating whether the ToggleButton is UP or DOWN and then use an Observer to display them in Label, as shown in the following code snippet:

    import io.reactivex.Observable;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class MyJavaFxApp extends Application {

@Override
public void start(Stage stage) throws Exception {

ToggleButton toggleButton = new ToggleButton("TOGGLE ME");
Label label = new Label();

Observable<Boolean> selectedStates =
valuesOf(toggleButton.selectedProperty());

selectedStates.map(selected -> selected ? "DOWN" : "UP")
.subscribe(label::setText);

VBox vBox = new VBox(toggleButton, label);

stage.setScene(new Scene(vBox));
stage.show();
}

private static <T> Observable<T> valuesOf(final
ObservableValue<T> fxObservable) {
return Observable.create(observableEmitter -> {

//emit initial state
observableEmitter.onNext(fxObservable.getValue());

//emit value changes uses a listener
final ChangeListener<T> listener = (observableValue, prev,
current) -> observableEmitter.onNext(current);

fxObservable.addListener(listener);
});
}
}
A JavaFX app backed by a hot Observable<Boolean> created off a ToggleButton's selection state
Note that if you are using OpenJDK, you will need to get the JavaFX library separately. It is easiest to use Oracle's official JDK, which includes JavaFX and is available at  http://www.oracle.com/technetwork/java/javase/downloads/index.html.

A JavaFX ObservableValue has nothing to do with an RxJava Observable. It is proprietary to JavaFX, but we can easily turn it into an RxJava Observable using the valuesOf() factory implemented earlier to hook ChangeListener as an onNext() call. Every time you click on the ToggleButton, the  Observable<Boolean> will emit a true or false reflecting the selection state. This is a simple example, showing that this Observable is emitting events but is also emitting data in the form of true or false. It will transform that boolean into a string and have an Observer modify a text of Label.

We only have one Observer in this JavaFX example. If we were to bring in more Observers to this ToggleButton's events after emissions have occurred, those new Observers will have missed these emissions.

UI events on JavaFX and Android are prime examples of hot Observables, but you can also use hot Observables to reflect server requests. If you created an Observable off a live Twitter stream emitting tweets for a certain topic, that also would be a hot Observable. All of these sources are likely infinite, and while many hot Observables are indeed infinite, they do not have to be. They just have to share emissions to all Observers simultaneously and not replay missed emissions for tardy Observers.

Note that RxJavaFX (as well as RxAndroid, covered in Chapter 11, RxJava on Android) has factories to turn various UI events into Observables and bindings for you. Using RxJavaFX, you can simplify the previous example using the valuesOf() factory.

Note that we did leave a loose end with this JavaFX example, as we never handled disposal. We will revisit this when we cover Disposables at the end of this chapter.

主站蜘蛛池模板: 新密市| 兴山县| 禄劝| 麻城市| 潢川县| 西丰县| 泽库县| 泸定县| 溧水县| 邯郸市| 锦屏县| 阳谷县| 普洱| 进贤县| 杂多县| 太湖县| 宝山区| 乌兰浩特市| 乌鲁木齐县| 徐闻县| 文山县| 泰来县| 塘沽区| 武冈市| 丽江市| 西乌| 涡阳县| 林口县| 屏边| 鄂托克旗| 余庆县| 克拉玛依市| 喀喇沁旗| 泰和县| 蒙自县| 四子王旗| 惠安县| 扬州市| 同仁县| 福泉市| 龙泉市|