简体   繁体   中英

RxJava emit items manually

I'm a newbie in RxJava world. I started few days ago and I'm trying to do something very concrete.

I would like to use RxJava to communicate some events from one class to other classes. My emitter class do some work and when finish I want notify that event to every subscribed class.

Also, I would like to don't loose any event, so if emitter finish an action and notifies to subscribers but no one consumes that event it should keep it.

I have been looking Subjects because i read was the good approach for emit by demand but I can't find one that solves my problem, may be I could try PublishSubject in the way they say in that link:

Note that a PublishSubject may begin emitting items immediately upon creation (unless you have taken steps to prevent this), and so there is a risk that one or more items may be lost between the time the Subject is created and the observer subscribes to it. If you need to guarantee delivery of all items from the source Observable, you'll need either to form that Observable with Create so that you can manually reintroduce “cold” Observable behavior (checking to see that all observers have subscribed before beginning to emit items), or switch to using a ReplaySubject instead.

At the moment I have an Observable that emits the complete list of events to every new Subscription:

protected List<T> commands = new ArrayList<>();
Observable<T> observe = Observable.defer(() -> Observable.fromIterable(commands));

Disposable subscribe(Consumer<T> onNext, Consumer<Throwable> onError) {
    return observe.subscribe(onNext/*, onError*/);
}

But this is far away from what I want. As I said I'm pretty noob with Rx, if I can't find a way I will end up using ReplaySubject (The complete list of commands would be repeated on every subscription but at least I will never lose one event).

EDIT:

Finally I split my problem in two parts. For emit items manually I use PublishSubject

PublishSubject<T> actionSubject = PublishSubject.create();
actionSubject.subscribe(onceAction);
actionSubject.onNext(action);

You are probably looking for a BehaviorSubject which replays last value emitted for every new subscriber.

Anyhow, you can create ReplaySubject with the factory method called createWithSize(capacity) to define size-bounded buffer, which discards the oldest item on overflow. There is also a method to create time-bounded buffer with similar behavior.

Isnt it what are you looking for?

    Observable<Integer> observable = Observable.create((ObservableEmitter<Integer> e) -> {
        for (int i = 0; i < 10; i++) {
            e.onNext(i);
        }
        e.onComplete();
    });

    System.out.println("FIRST");
    observable
            .doOnComplete(() -> System.out.println("FIRST COMPLETE"))
            .subscribe(System.out::println);
    System.out.println("SECOND");
    observable
            .doOnComplete(() -> System.out.println("SECOND COMPLETE"))
            .subscribe(System.out::println);

Output:

FIRST
0
1
2
3
4
5
6
7
8
9
FIRST COMPLETE
SECOND
0
1
2
3
4
5
6
7
8
9
SECOND COMPLETE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM