#android #kotlin #lambda #repository #rx-java
#Android #kotlin #лямбда #репозиторий #rx-java
Вопрос:
Допустим, у меня есть приложение для Android со следующим классом репозитория для извлечения объектов из API:
override fun fetchOrderById(orderId: Long): Single<List<ItemRow>> {
return api.fetchOrderByIdObservable(orderId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map { orderResponse ->
orderResponse.items.map { deliveryItem ->
deliveryItem.asItemRow()
}
}
}
override fun fetchOrders(): Single<OrdersResponse> {
return api.fetchOrdersObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
override fun fetchAllOrders(): Single<List<ItemRow>> {
// TODO
}
Со следующим классом данных:
class OrdersResponse(@SerializedName("orders") val orders: List<Long>)
class OrderResponse(@SerializedName("items") val items: List<DeliveryItem>)
Прямо сейчас я могу использовать fetchOrderById, чтобы получить все элементы доставки (ItemRow) для определенного OrderID в качестве объекта домена в моем приложении для отображения в списке. Как я могу использовать fetchOrders , который возвращает список идентификаторов заказов, чтобы получить все элементы доставки для всех заказов? Какие операторы были бы полезны здесь? Я поиграл с flatMap, но не смог заставить его работать. Ссылка на статьи тоже будет . Спасибо!
Ответ №1:
нужные вам операторы: switchMap()
, flatMap()
, fromArray()
, toList()
, map()
это будет что-то вроде этого:
fun fetchAllOrders(): Observable<List<ItemRow>> {
return fetchOrders()
.toObservable()
.switchMap { ordersResponse ->
Observable.fromIterable(ordersResponse.orders)
.flatMap {orderId -> fetchOrderById(orderId).toObservable() }
.toList()
.toObservable()
}
.map { list -> list.flatten() }
}
Комментарии:
1. Хммм, спасибо за ответ, но этот не работает. В .
flatMap {orderId -> fetchOrderById(orderId) }
передается список <Длинный> (список идентификаторов порядка), а не длинный (идентификатор порядка)! :/2. @sorry_I_wont произошла ошибка опечатки, пожалуйста, смотрите Отредактированный ответ. Вам нужно перейти
ordersResponse.orders
вObservable.fromArray
3. Я не думаю, что проблема в опечатке, у меня эта ошибка в теле switchMap:
Type mismatch. Required: ObservableSource<out (???..???)>! Found: Single<(Mutable)List<List<ItemRow>!>!>! Type mismatch. Required: ObservableSource<out TypeVariable(R)!>! Found: Single<(Mutable)List<List<ItemRow>!>!>!
4. Отредактировано снова, добавьте
.toObservable()
послеfetchOrders()
5. Спасибо, на этот раз он скомпилирован! Это странно, в чем разница между «вызовом ToObservable для fetchOrders()» и «если fetchOrders() возвращает наблюдаемое вместо одного»? Потому что, когда я меняю его на fetchOrders(), чтобы возвращать наблюдаемый <OrdersResponse> вместо Single , это не сработает, но они должны быть одинаковыми!!
Ответ №2:
В конечном итоге это сработало:
public fun fetchAllItems(): Observable<List<ItemRow>> {
return networkService.api.fetchOrdersObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap { orderResponse -> Observable.just(orderResponse.orders) }
.flatMapIterable { id -> id }
.flatMap { id -> fetchOrderById(id) }
.flatMapIterable { itemRow -> itemRow }
.toList()
}