Как составить Observable с поведением До / После - PullRequest
0 голосов
/ 03 ноября 2018

Предположим, у меня есть Observable, и он будет излучать не более 1 элемента.

Я бы хотел сделать что-то до и после излучения элемента. Как мне поступить с операторами для создания нового Observable?

Скажите, что я хочу отследить мою наблюдаемую в следующей последовательности:

  1. отметка времени начала журнала (span.start ())
  2. сделать реальный бизнес, чтобы испустить элемент.
  3. отметка времени окончания журнала (span.finish ())

для "после", может быть, я могу использовать doOnComplete и doOnError но я понятия не имею, как это сделать "до"

Заранее спасибо!

Edit:

Вот 1 способ, которым я могу придумать, не уверен, что это лучший способ, или есть потенциальные проблемы:

Future<String> f = CompletableFuture.supplyAsync(() -> {
  return "Do Biz";
});

Observable<String> original = Observable.from(f).doOnCompleted(() -> {
  System.out.println("inner after");
});
Observable<String> decorated = Observable.defer(() -> {
  System.out.println("Before");
  return original;
}).doOnCompleted(() -> {
  System.out.println("outer after");
});

decorated.subscribe(System.out::println);

Спасибо

Leon

1 Ответ

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

Я думаю, что более чистый способ сделать это - использовать doOnSubscribe, например:

Observable<String> createInitialObservable() {
    return Observable.fromCallable(() -> {
        System.out.println("Execution...");
        return "Do Biz";
    });
}

Observable<String> decorateObservable(Observable<String> source) {
    return source
            .doOnSubscribe(d -> System.out.println("Before execution"))
            .doOnNext((item) -> System.out.println("Received item '" + item + "'"))
            .doOnComplete(() -> System.out.println("After execution"));
}

void test() {
    Observable<String> source = createInitialObservable();
    decorateObservable(source)
            .subscribe(System.out::println);
}

Вывод будет:

Before execution
Execution...
Received item 'Do Biz'
Do Biz
After execution

Тем не менее, ваше решение является полностью действительным и выполнит работу. Просто, на мой взгляд, удобнее иметь отдельное место для обратного вызова перед выполнением.

...