Ожидание создания объекта или немедленный доступ к нему, если он уже существует - PullRequest
0 голосов
/ 27 октября 2018

Сегодня я столкнулся со следующей проблемой: у нас есть класс Foo, в котором есть экземпляр Bar.Метод initBar() вызывается в некоторый момент в течение жизненного цикла класса (который очень асинхронный, много RxJava), и он делает bar = new Bar()

Теперь проблема в том, что я хочу получить доступ к barвнутри какого-то другого метода doStuff(), который не гарантированно вызывается после initBar(), поэтому bar может все еще быть null или уже существовать.

Если bar уже существует, я хочу сразу запустить синхронную функцию analyze(bar), если она все еще null - я хочу запланировать ее запуск после установки bar (как частьinitBar() звонок).

Бонусные вопросы : как указать, в каком потоке analyze(bar) должен выполняться;что если несколько методов хотят получить доступ к bar;как безопасно отменить их.

Теперь я знаю, как реализовать это с помощью RxJava: добавьте дополнительно PublishSubject<Bar> subject и подпишитесь на него, вызывая .repeat(), чтобы получить значение, если оно уже установлено, а затем изinitBar() до subject.onNext(bar).Это легко.Он даже охватывает случай доступа к нему из нескольких мест и указания потока для выполнения кода.

Но я чувствую, что изобретаю колесо здесь - возможно, есть решение для этого типа проблем, когда вы хотите получить доступ к объекту, не беспокоясь о том, установлен он или нет.Следует ли считать Promise и делать это с CompletableFuture или JDeferred ?Или уже есть какой-нибудь хороший рецепт RxJava для этого?Должно быть что-то чистое и простое ...

Вот полный код Foo для справки:

class Foo {
    Bar bar;

    void initBar() { bar = new Bar(); }

    void doStuff() {
         //This is the missing piece
         doWhenBar(bar -> analyze(bar));
    }

    void lifecycle1() {
        Observable.create(..)
            ...
            .doOnNext(this::initBar())
            ...
    }

    void lifecycle2() {
        Observable.create(..)
            ...
            .subscribe(this::doStuff())
    }

    //More methods where lifecycle1() and lifecycle2() can be called in random order
    ...
}

1 Ответ

0 голосов
/ 04 ноября 2018

Если bar создается только один раз, используйте SingleSubject, и теперь вы можете реагировать на создаваемое Bar:

class Foo {
    final SingleSubject<Bar> bar = SingleSubject.create();

    void initBar() { bar.onSuccess(new Bar()); }

    Single<Bar> doStuff() {
         //This is the missing piece
         return bar.observeOn(Schedulers.computation())
         .doOnSuccess(b -> analyze(b));
    }

    void lifecycle1() {
        Observable.create(..)
        ...
        .doOnNext(this::initBar())
        ...
    }

    void lifecycle2() {
        Observable.create(..)
        ...
        .concatMapSingle(this::doStuff)
        .subscribe(...)
    }

// More methods where lifecycle1() and lifecycle2()
// can be called in random order
...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...