У меня довольно стандартная проблема с разбивкой по страницам API, с которой вы можете справиться с некоторой простой рекурсией. Вот пример:Paginate Наблюдаемые результаты без рекурсии - RxJava
public Observable<List<Result>> scan() {
return scanPage(Optional.empty(), ImmutableList.of());
}
private Observable<?> scanPage(Optional<KEY> startKey, List<Result> results) {
return this.scanner.scan(startKey, LIMIT)
.flatMap(page -> {
if (!page.getLastKey().isPresent()) {
return Observable.just(results);
}
return scanPage(page.getLastKey(), ImmutableList.<Result>builder()
.addAll(results)
.addAll(page.getResults())
.build()
);
});
}
Но это, очевидно, может создать массивный столбец. Как я могу сделать это обязательно, но поддерживать поток Observable?
Вот императив блокировании пример:
public List<Result> scan() {
Optional<String> startKey = Optional.empty();
final ImmutableList.Builder<Result> results = ImmutableList.builder();
do {
final Page page = this.scanner.scan(startKey);
startKey = page.getLastKey();
results.addAll(page.getResults());
} while (startKey.isPresent());
return results.build();
}
К сожалению, я не думаю, что будет работать. Результат будет первым результатом сканирования, так как это будет установлено, но поток основного потока выполнения обнаружит, что currentKey еще не установлен, и выйдите. –
Похоже, вы правы. Проблема - это ключ. Если нет обычного способа его генерации, например. «1», «2» и т. Д., Тогда я думаю, что вы застряли с рекурсивным решением, которое имеет свои проблемы, если у вас слишком много страниц. – JohnWowUs
См. Отредактированный ответ для хакерского решения с использованием темы и побочных эффектов. – JohnWowUs