Я новичок в RxJava, и есть много примеров и ответов, но мне трудно собрать воедино что-то, что решает все мои проблемы.
Код ниже, кажется, работает, за исключением того, что я иногда получаю результаты не по порядку. Поэтому я думаю, что мне нужно ввести switchMap, но я не уверен, где именно, и мне интересно, не сделал ли я уже излишне сложные вещи, например, не странно ли подписываться на RxBinding и отдельно подписываться на сетевой вызов?
view.autocompleteText() — это RxBinding. Я хочу получить от этого текст, вызвать службу модернизации и обновить представление с результатами, со всеми прибамбасами, такими как отображение/скрытие счетчика, и обработкой ошибок для сетевого вызова, который не уничтожит все это и сделает мой текстовое поле не отвечает.
private void handleAutocompleteText() {
mCompositeDisposable.add(view.autocompleteText()
.debounce(400, TimeUnit.MILLISECONDS)
.filter(s -> s.length() >= resources.getAutocompleteThreshold())
.observeOn(threads.main())
.doOnNext(s -> view.setProgressVisible(true))
.subscribe(s -> {
mCompositeDisposable.add(mAutocompleteService.query(s.toString())
.subscribeOn(threads.io())
.observeOn(threads.main()).toObservable()
.retry(3)
.doOnNext(response -> {
if (response.getStatus() != 200)
throw new RuntimeException("Server error " + response.getStatus());
})
.map(response -> response.getData())
.subscribe(items -> {
view.setProgressVisible(false);
view.updateList(items);
}, error -> {
view.setProgressVisible(false);
view.showMessage(resources.getListError());
}));
}, error -> {
view.setProgressVisible(false);
view.showMessage(resources.getListError());
}
)
);
}
Есть ли лучший способ сделать это, и где я могу ввести switchMap, чтобы отбрасывать любые поиски во время полета и обновлять представление только с результатами последнего? И если ответ кардинально отличается, я был бы очень признателен за пошаговое руководство.
Заранее спасибо!!
Я не уверен, что ты этого хочешь. Но это может дать вам подсказки и решения.
Давайте посмотрим код. switchMap получает параметр из представления и изменяет observable на resrofit observable. И затем он возвращает ответ от API call. После всего этого вы можете получить ответ и использовать ответ.
Если код не работает, дайте мне знать.
mCompositeDisposable.add(
view
.autocompleteText()
.debounce(400, TimeUnit.MILLISECONDS)
.filter({ s -> s.length() >= resources.getAutocompleteThreshold() })
.observeOn(threads.main())
.doOnNext({ s -> view.setProgressVisible(true) })
.map({ s -> s.toString())}
.switchMap({ text -> mAutocompleteService.query(text))}
.subscribeOn(threads.io())
.observeOn(threads.main())
.retry(3)
.doOnNext({ response ->
if (response.getStatus() !== 200)
throw RuntimeException("Server error " + response.getStatus())
})
.map({ response -> response.getData() })
.subscribe({ items ->
view.setProgressVisible(false)
view.updateList(items)
}, { error ->
view.setProgressVisible(false)
view.showMessage(resources.getListError())
})
)
the whole chain goes dead <-- Что значит? disposable был disposed? Интересно ? Вы видели сообщения в subscribe или logcat?
Мне жаль! Это работает с switchMap! Я добавил в DifferentUntilChanged(), и именно это остановило его испускание. Не уверен, почему это не работает, как я ожидаю, но это другой вопрос. Спасибо!!
Спасибо! Я попробовал что-то подобное, и это, похоже, работает, но как только возвращаются успешные результаты, вся цепочка отключается, поэтому пользователь не может удалить текст и начать поиск с другого. Я думаю, это имеет смысл, что наблюдатель закончился, когда вы достигли успеха, и почему я получил 2 подписки. Мне нужно, чтобы наблюдатель текстового поля продолжал работать, пока страница активна. Может быть, я не могу использовать switchMap и должен использовать стратегию переключения, которую я узнал из этого сумасшедшего видео: youtu.be/rUZ9CjcaCEw. Думаю, это не совсем одно и то же.