Правильное использование RxSwift для цепочки запросов, flatMap или что-то еще?
Прежде всего, я новичок в rxswift, поэтому я думаю, что ответ очевиден, но в данный момент я не могу найти решение самостоятельно.
У меня есть две функции:
func downloadAllTasks() -> Observable<[Task]>
func getTaskDetails(taskId: Int64) -> Observable<TaskDetails>
Первый загружает список объектов Task с помощью сетевого запроса, второй загружает подробности задачи для отдельной задачи (используя ее идентификатор)
Чего я хочу добиться, так это загрузить все задачи, а затем для каждой задачи я хочу загрузить ее детали и подписаться на событие, которое будет запущено, когда все детали задач будут готовы.
Поэтому я думаю, что мне следует как-то подписаться на Observable <[TaskDetails]>, но я не знаю, как это сделать.
downloadAllTasks()
.flatMap{
... // flatMap? something else?
}
.subscribe(
onNext: { details in
print("tasks details: \(details.map{$0.name})")
})
.addDisposableTo(disposeBag)
//РЕДАКТИРОВАТЬ
Благодаря ответу Сильвана Мосбергера я гораздо ближе к решению. Осталась одна проблема. Теперь у меня есть что-то вроде этого:
downloadAllTasks()
.flatMap{ Observable.from($0) }
.map{ $0.id }
.flatMap{ [unowned self] id in
self.getTaskDetails(taskId: id).catchError{ error in
print("$$ Error downloading task \(id)")
return .empty()
}
}
.do(onNext: { _ in
print(" $$ single task details downloaded")
} )
.toArray()
.debug("$$ task details array debug", trimOutput: false)
.subscribe({ _ in
print("$$ all tasks downloaded")
})
.addDisposableTo(disposeBag)
Выход
$$ task details array debug -> subscribed
$$ single task details downloaded
$$ single task details downloaded
$$ single task details downloaded
Доступно 3 задачи, так что вы можете видеть, что все они загружены правильно, но по какой-то причине результат toArray () - (Observable<[TaskDetails]>
) не выдает «onNext», когда все детали задачи готовы.
// Редактируем еще раз
Хорошо, я добавляю упрощенную версию функций, обеспечивающих наблюдаемые, может быть, это поможет
func downloadAllTasks() -> Observable<Task> {
return Observable.create { observer in
//... network request to download tasks
//...
for task in tasks {
observer.onNext(task)
}
observer.onCompleted()
return Disposables.create()
}
}
func getTaskDetails(id: Int64) -> Observable< TaskDetails > {
return Observable.create { observer in
//... network request to download task details
//...
observer.onNext(taskDetails)
return Disposables.create()
}
}