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

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.

主站蜘蛛池模板: 集安市| 南丰县| 万安县| 永登县| 蓝山县| 安平县| 顺平县| 新蔡县| 陵川县| 四子王旗| 山阳县| 合山市| 东阿县| 龙井市| 浙江省| 炉霍县| 邓州市| 彭水| 麻栗坡县| 宝鸡市| 江西省| 杂多县| 邻水| 行唐县| 汝阳县| 屏东县| 浮梁县| 江口县| 明星| 澄城县| 治多县| 平昌县| 岚皋县| 望都县| 和平区| 北京市| 沭阳县| 闵行区| 锦州市| 托克逊县| 闻喜县|