循环通过可观察的流

时间:2015-12-03 00:14:58

标签: rx-java

我有一个基本上模拟状态图的observable流。例如:

whenThisHappens()
    .switchMap(i -> {
        if (i.isThisThing()) {
            return whenThatHappens();
        } else {
            return nothingHappened();
        }
    }
    .subscribe(thing -> {
        if (thing.isThatThing()) {
            log("Got that thing");
        } else {
            log("Got nothing");
        }
    });

问题是我想循环登录直到某些事件发生(这是在Android上的长期运行服务)。现在我能够通过将observable保存在变量中,订阅它然后取消订阅并重新订阅它来onComplete

来实现这一目标。
obs = whenThisHappens()
    .switchMap(i -> {
        if (i.isThisThing()) {
            return whenThatHappens();
        } else {
            return nothingHappened();
        }
    }
    .doOnNext(thing -> {
        if (thing.isThatThing()) {
            log("Got that thing");
        } else {
            log("Got nothing");
        }
    })
    .doOnComplete(i -> {
        obs.unsubscribe();
        obs.subscribe();
    }
    obs.subscribe();

但我觉得我在这里做了一些非常错误的事情。有没有更好的方法来实现这一目标?我看了retry但是为了让它重试而抛出错误似乎和我现在所做的一样糟糕。

2 个答案:

答案 0 :(得分:1)

我认为使用PublishSubjectBehaviorSubject可以更好地完成您的目标。

该流会在主题上发布会触发您订阅的项目。

这是我刚才写的事件流类:

public class SubjectEventStream implements IEventStream {
    private final BehaviorSubject<IEvent> stream = BehaviorSubject.create();

    @Override
    public void publish(Observable<IEvent> event) {
        event.doOnNext(stream::onNext).subscribe();
    }

    @Override
    public Observable<IEvent> observe() {
        return stream;
    }

    @Override
    public <T> Observable<T> observe(Class<T> eventClass) {
        return stream.ofType(eventClass);
    }
}

在此处查看更多信息:

http://reactivex.io/documentation/subject.html

http://akarnokd.blogspot.com/2015/06/subjects-part-1.html

答案 1 :(得分:0)

阅读您的代码看起来像是filter

whenThisHappens()
         # ignore uninteresting things
        .filter(i -> i.isThisThing())
         # do stuff on interesting things
        .subscribe(item -> log("Got: " + item.toString()));

此基本subscribe还有两个可选参数,它们是on-error函数和on-complete函数,如果需要可以使用 - 但订阅会在这里自动管理。