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

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.

主站蜘蛛池模板: 邢台县| 方山县| 株洲县| 延长县| 比如县| 开远市| 鲜城| 思南县| 永靖县| 日土县| 郁南县| 重庆市| 婺源县| 长治市| 陇西县| 福建省| 清水县| 临沭县| 涿鹿县| 米泉市| 新沂市| 延川县| 阳原县| 苗栗县| 黑水县| 崇州市| 房产| 凤凰县| 吉隆县| 通化县| 北碚区| 白河县| 徐州市| 上思县| 平南县| 定边县| 慈溪市| 金川县| 桂平市| 合川市| 包头市|