RxJava: Создать элементы в списке и вернуть новый список - PullRequest
0 голосов
/ 02 октября 2018

Rx noobie здесь: есть идеи, как этого добиться?:

У меня есть список элементов из пользовательского интерфейса, и я хотел бы разместить их на сервере.Мне нужен список POST-элементов, возвращаемых с сервера (чтобы использовать выданные сервером идентификаторы, временные метки и т. Д.).

Извините за длинные примеры, но вот код, который я изо всех сил стараюсь заставить работать:

/**
 * create each item (POST) in the list and return the list
 * of newly created ones
 */
fun postItems(items: List<Item>): Maybe<List<Item>> {
    // loop through all items, making a network call for each and return the
    // list of POSTed items

    // attempt 1
    // Failed type inference. Expected type mismatch:
    // Expected: Maybe<List<Item>>
    // Found: List<Maybe<Item>>
    return items.map {
        postItem(it)
    }

    // attempt 2: 'extract' each item in resulting observable and
    // shove it back to original list
    return Maybe.just(items.map {
        postItem(it!!)
                // 'extract' item from observable
                .flatMap {
                    // error: Type mismatch.
                    // Required ((Item) -> MaybeSource<out (???...???)>!)!
                    // Found (Item) -> Item
                    it
                }
    })

    // attempt 3: convert a Maybe to Flowable to collect all items from post
    // and emit them as a single list
    // Type mismatch. Required:(((Mutable)List<Item!>) -> SingleSource<out (???...???)>!)!
    // Found: ((Mutable)List<Item!>) -> (Mutable)List<Item!>
    return items.forEach {
        postItem(it!!).toFlowable().toList().flatMap { it }
    }

    // attempt 4: modify attempt 3 with concatMap:
    // Type mismatch. Required:((List<Item!>) -> MaybeSource<out (???...???)>!)!
    // Found: (List<Item!>) -> List<Maybe<Item>>
    return Maybe.just(items)
            // wait for each observable to finish all the work 
            // until the next one is processed
            .concatMap({
                it.map { addItem(it!!) }
            }).toFlowable()
            .toList().toMaybe()

    // attempt 6: blocking call on each API request.
    // results in android.os.NetworkOnMainThreadException
    return Maybe.just(places.map {
        addPlace(it!!).blockingGet()
    })
}

fun postItem(item: Item): Maybe<Item> {
    return networkService.post(item) // async call to API, returns Maybe<Item>
}

ОБНОВЛЕНИЕ

Я попробовал подход, предложенный @AlexeySoshin ниже, но все еще есть некоторые моменты путаницы:

Я попробовал второй, более короткий подходно вызов дооснащения не происходит по какой-то причине :(, то есть конечные точки сетевых служб не затронуты).Он немного изменен, потому что я не смог заставить работать оболочку rx-kotlin, но я предполагаю, что это примерно эквивалентно этому:

fun addItems(items: List<Item?>): Flowable<Maybe<Item>> {
    return Flowable.fromIterable(items).map {
        // tried items.toFlowable().map but got 'Unresolved reference toFlowable
        // even after adding rx-kotlin to project via gradle
        return@map postItem(it)
    }
}

Моя сетевая служба успешно работает для одного элемента с этим кодом:

// works as expected
fun postOneItem(item: Item): Maybe<Item> {
    return postItem(item)
}

// also works
fun postOneItemFlowable(item: Item): Flowable<Item> {
    return postItem(item).toFlowable()
}


// this variant didn't work
fun postOneItemFlowable(item: Item): Flowable<Maybe<Item>> {
    return Flowable.just(postItem(item))
}

Как сделать так, чтобы Flowable<Maybe<Item>> звонки проходили успешно?(или Flowable<List<Item>>, что в конечном итоге было бы ближе к тому, что мне нужно)

Наконец, как получить фактический список вывода из Flowable<Maybe<Item>>?Было бы полезно увидеть, как блок .subscribe() может выглядеть, чтобы «извлечь» этот окончательный список.Вот как выглядит мой текущий код подписки:

...
private fun createItem(item: Item) {
    disposables.add(
            addItemUseCase.postOneItem(item)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe({
                        Timber.d("one item posted: $it")
                    }, { /* error handler *//})
}
...

1 Ответ

0 голосов
/ 02 октября 2018

Вы можете сделать что-то вроде этого:

fun postItems(items: List<Item>): Maybe<List<Item>> {
    return items.toFlowable().map {
        postItem(it).blockingGet()
    }.toList().toMaybe()
}

Но я не уверен, что вы на самом деле это имеете в виду, поскольку ваш Maybe на самом деле не Maybe.

Изменение подписи таким образом будет иметь больше смысла:

fun postItems(items: List<Item>): Flowable<Maybe<Item>> {
    return items.toFlowable().map {
        postItem(it)
    }
}
...