-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JavaFxObservable.actionEventsOf().subscribeOn(Schedulers.newThread()) misses some emissions #77
Comments
Thank you, I'm glad you like it. There should never be a good reason to use It's interesting and probably not a good behavior though for folks who don't know better. I'm not quite sure what's causing the issue since there is already an internal However, I have stopped putting That is interesting regardless though. |
It's going to be a long one but I would really appreciate you read it. import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
public class ObservableListApp {
public static void main(String[] args) {
ObservableList<String> letters = FXCollections.observableArrayList();
letters.addListener((ListChangeListener<String>) change -> {
while (change.next()) {
if (change.wasAdded()) {
change.getAddedSubList().forEach(letter -> System.out.println("[" + Thread.currentThread().getName() + "] letter=" + letter));
}
}
});
letters.add("Alpha");
letters.add("Beta");
}
} Above app works perfectly fine. import java.util.concurrent.Executors;
import io.reactivex.Observable;
import io.reactivex.rxjavafx.observables.JavaFxObservable;
import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
import io.reactivex.schedulers.Schedulers;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ModelSideObservableListApp extends Application {
private final TextField textField = new TextField();
private final Button button = new Button("Run!");
private final Label label = new Label();
private final HBox hBox = new HBox(textField, button, label);
private final Scene scene = new Scene(hBox);
private final ObservableList<String> list = FXCollections.observableArrayList();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
hBox.setPrefSize(400, 100);
stage.setScene(scene);
stage.show();
JavaFxObservable.actionEventsOf(button)
.map(actionEvent -> textField.getText())
.observeOn(Schedulers.from(Executors.newSingleThreadExecutor()))
.map(Integer::valueOf)
.flatMapSingle(i -> Observable.range(1, i).map(String::valueOf).toList())
.doOnNext(next -> System.out.println("[" + Thread.currentThread().getName() + "] next=" + next))
.subscribe(list::addAll);
JavaFxObservable.additionsOf(list)
.subscribeOn(Schedulers.from(Executors.newSingleThreadExecutor()))
.doOnNext(next -> System.out.println("[" + Thread.currentThread().getName() + "] next=" + next))
.observeOn(JavaFxScheduler.platform())
.subscribe(next -> label.setText("Just got " + next + " new emissions"));
}
} The idea behind the app is (and I'm a little bit confused it works as I expected):
(https://docs.oracle.com/javase/8/javafx/api/javafx/collections/ListChangeListener.Change.html)
The final point is - observable collections should work by default on Schedulers.immediate() and get an option of change Scheduler just like Observable.interval(period, unit, scheduler) |
🤔 Thanks for putting this reasoning together. I do agree that JavaFX ObservableCollection should be agnostic to which thread it modifies/fires on. However, I don't know if this is kosher to make You see, the Events on If you haven't gotten into subjects yet, my Learning RxJava book is $10 now. I've seen it go on sale for $5 on Black Fridays... which is this Friday. |
I was learning about concurrency from your book (btw it's great) and ran into this.
When creating an Observable using JavaFxObservable factory methods and following it with subscribeOn(Scheduler) the Scheduler should be suppressed by default JavaFxScheduler.platform().
It is exectly what happens when using JavaFxObservable.actionEventsOf() but there is strange behaviour using it with JavaFxObservable.additionsOf().
It works fine (both subscribers receive their emisions) when new list element is added from inside button click handler but adding element straight from the main method causes lack of emissions to Observer[2].
The text was updated successfully, but these errors were encountered: