4

I have code that does blocking operation in while loop (downloads some data from a server). Client does not know how many items are going to be returned in each step. Loop breaks when N items are downloaded.

val n = 10
val list = ArrayList<T>()

while (list.size < n) {
    val lastItemId = list.last()?.id ?: 0
    val items = downloadItems(lastItemId)
    list.addAll(items)
}

downloadItems performs blocking HTTP call and returns list. Now let's assume downloadItems changes and new return type is Observable<Item>. How could I change the code to use RxJava without performing something like blockingGet?

0

2 Answers 2

10

You could use repeatUntil to achieve this:

var totalItems = 0    
var id = 0
Observable.fromCallable {
            downloadItems(id)
        }
        .flatMap {
            list ->
                totalItems += list.size
                id = list.last()?.id ?: 0
                Observable.just(list)
        }
        .repeatUntil({totalItems > n})
        .subscribe({result -> System.out.println(result) })
Sign up to request clarification or add additional context in comments.

Comments

1

I think this is elegant way

int n = 10;
Observable.range(0,n)
        .flatMap(i -> downloadItems(i))
        .toList()
        .subscribe(itemsList -> itemsList.forEach(item -> System.out.println(item)));

2 Comments

That would call downLoadItems 10 times. I just want to download 10 items. Each call of downloadItems could return more than 0 items, exact number of items is unknown.
I found question that is similar to yours stackoverflow.com/questions/50827046/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.