如何只创建一次observable?

时间:2017-04-04 08:29:09

标签: rx-java

我有一个特定的功能,只要有人订阅,我就会发出项目。此外,此功能只应执行一次,如果有人订阅它,则不应执行

 Observable<CharSequence> observable = Observable.create(subscriber -> {

            try {

                sseEventSource.connect(); //this should be called once when created;

                final SseEventReader sseEventReader = sseEventSource.getEventReader();
                SseEventType type = sseEventReader.next();
                while (type != SseEventType.EOS) {
                    if (type != null && type.equals(SseEventType.DATA) && sseEventReader.getData() != null) {
                        CharSequence data = sseEventReader.getData();
                        if (!subscriber.isUnsubscribed()) {
                            subscriber.onNext(data);
                        }
                    }
                    type = sseEventReader.next();
                }
                sseEventSource.close();
                Log.d("SseService", "closed");
                if (!subscriber.isUnsubscribed()) {
                    subscriber.onCompleted();
                }
            } catch (URISyntaxException | IOException e) {
                if (!subscriber.isUnsubscribed()) {
                    subscriber.onError(e);
                }
            }

2 个答案:

答案 0 :(得分:1)

尝试share()运算符。

Observable<CharSequence> observable = Observable.create(subscriber -> {

        try {

            sseEventSource.connect(); //this should be called once when created;

            final SseEventReader sseEventReader = sseEventSource.getEventReader();
            SseEventType type = sseEventReader.next();
            while (type != SseEventType.EOS) {
                if (type != null && type.equals(SseEventType.DATA) && sseEventReader.getData() != null) {
                    CharSequence data = sseEventReader.getData();
                    if (!subscriber.isUnsubscribed()) {
                        subscriber.onNext(data);
                    }
                }
                type = sseEventReader.next();
            }
            sseEventSource.close();
            Log.d("SseService", "closed");
            if (!subscriber.isUnsubscribed()) {
                subscriber.onCompleted();
            }
        } catch (URISyntaxException | IOException e) {
            if (!subscriber.isUnsubscribed()) {
                subscriber.onError(e);
            }
        }).share() ;

如果你真的想要一个热的可观察性使用publish()connect()来发起观察,即使没有人订阅。

答案 1 :(得分:0)

您可以使用Subjects完成此操作,例如:

public static void main(String[] args) {
    Main m = new Main();
    m.getChanges().subscribe(x -> {
        //Data
    }, e -> {
        //Errors
    });
    m.connect();
}

private PublishSubject<CharSequence> ps = PublishSubject.create();

public void connect() {
    sseEventSource.connect();
}

public Observable<CharSequence> getChanges() {
    try {
        final SseEventReader sseEventReader = sseEventSource.getEventReader();
        SseEventType type = sseEventReader.next();
        while (type != SseEventType.EOS) {
            if (type != null && type.equals(SseEventType.DATA) && sseEventReader.getData() != null) {
                CharSequence data = sseEventReader.getData();
                ps.onNext(data);
            }
            type = sseEventReader.next();
        }
        sseEventSource.close();
        ps.onComplete();
    } catch (URISyntaxException | IOException e) {
        ps.onError(e);
    }
    return ps;
}

这样,您可以根据需要订阅/取消订阅主题更改,并且只建立一次连接。如果您想收到缓冲更改,请考虑使用ReplaySubject