RxJava doOnError против onError

1

Я пытаюсь использовать следующий код

initLocalSettingsIfNeed()
                            .andThen(initGlobalSettingsIfNeed(configuration))
                            .doOnComplete(callback::onSuccess)
                            .doOnError(throwable -> callback.onError(throwable.getLocalizedMessage()))
                            .subscribe();

Но у меня есть исключение

Исключение не было обработано из-за отсутствия обработчика onError в вызове метода subscribe().

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

Теги:
rx-java
rx-java2

2 ответа

2
Лучший ответ

Что касается вашего исходного вопроса, вы должны знать, что doOnError не является заменой onError. У вас есть хорошее и краткое объяснение этого в этом блоге:

На самом деле есть одно ключевое различие между ними. doOnError() в основном только запускает обратный вызов, а затем передает обнаруженные ошибки в нисходящий поток. Таким образом, если весь поток подписан без обратного вызова onError в методе subscribe(), ваше приложение будет аварийно завершено с помощью OnErrorNotImplementedException.

Обратный вызов onError в методе subscribe(), с другой стороны, использует ошибки. Это означает, что он будет отлавливать ошибки и позволять вам обрабатывать их без повторного вызова ошибок. Давайте напишем еще один unit тест для подтверждения:

О предупреждении, которое вы упоминаете в одном комментарии:

Этот подход работает, но у меня есть предупреждение "результат подписки не используется", так как я знаю, что его нужно автоматически удалять при вызове onError или onComplete, есть ли способ избежать этого предупреждения? - Павел Полей

Хороший подход заключается в том, что ваши методы внутри вашего Repository возвращают Observable, а затем вы можете подписаться на них в своей ViewModel. Затем в каждом классе ViewModel вас может быть переменная-член с CompositeDisposable где вы можете добавить одноразовую каждую подписку в Observables, возвращаемые вашим хранилищем. Наконец, вы должны переопределить метод onCleared чтобы утилизировать все одноразовые материалы, хранящиеся в CompositeDisposable.

public class MyViewModel extends ViewModel {

    private MyRepository myRepository;
    private final CompositeDisposable disposables;

    @Inject
    public MyViewModel(MyRepository myRepository) {
        ...
        this.myRepository = myRepository;
        disposables = new CompositeDisposable();
        ...
    }

    public void callObservableInRepository() {
         disposables.add(myRepository.myObservable()
                              .subscribe(onSuccess -> {...} , onError -> {...}));
    }

    @Override
    protected void onCleared() {
        disposables.clear();
    }

}
2

попробуй это

initLocalSettingsIfNeed()
    .andThen(initGlobalSettingsIfNeed(configuration))
    .subscribe({completed->
        callback.onSuccess()
    },{throwable->
        callback.onError(throwable.getLocalizedMessage())
    })
  • 0
    Этот подход работает, но у меня есть предупреждение «результат подписки не используется», так как я знаю, что его нужно автоматически удалять при вызове onError или onComplete, есть ли способ избежать этого предупреждения?
  • 0
    например, вы можете добавить его в CompositeDisposable () и утилизировать после того, как он больше не нужен. Например, одноразовые. Add (в коде выше) и затем одноразовые.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню