Firs of whole Я новичок в rxswift, поэтому, я думаю, ответ очевиден, но на данный момент я не могу найти решение самостоятельно.Правильное использование RxSwift для запросов на цепочку, flatMap или что-то еще?
У меня есть две функции:
func downloadAllTasks() -> Observable<[Task]>
func getTaskDetails(taskId: Int64) -> Observable<TaskDetails>
Сначала один загружает список Задачу объектов с помощью запроса сети, второй один загрузки сведений о задаче для sepcific задачи (используя его идентификатор)
Что я хочу от достичь - загрузить все задачи, а затем для каждой задачи я хочу загрузить ее данные и подписаться на событие, запущенное, когда все детали задач готовы.
Итак, я должен как-то подписаться на Observable < [TaskDetails]>, но я не знаю, как это сделать.
downloadAllTasks()
.flatMap{
... // flatMap? something else?
}
.subscribe(
onNext: { details in
print("tasks details: \(details.map{$0.name})")
})
.addDisposableTo(disposeBag)
// EDIT
Благодаря Сильван Mosberger ответ я гораздо ближе к решению. Осталась одна проблема. Теперь у меня есть что-то вроде этого:
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» после того, как все детали задачи готовы.
// Edit еще раз
Хорошо, я добавляю упрощенную версию функций, обеспечивающих наблюдаемыми, может быть, это поможет что-то
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()
}
}
Приятного и чистое объяснение, спасибо. И он работает почти так, как я хочу. Почти, beacause у меня проблема с последней частью - toArray(). Без этой части абонент уведомляется должным образом о событиях загрузки сведений о задачах. С toArray я бы ожидал, что я получу уведомление в onNext абонента, когда будут загружены все детали задачи, но onNext не вызывается вообще. Вы видите, что может быть проблемой? – Wujo
@Wujo Когда при загрузке одной детали детали задается ошибка, окончательный 'Observable' будет ошибкой. Вы должны иметь возможность проверить это с помощью '.debug()' перед '.toArray()'. Я отредактировал мой ответ, если вы хотите его завершить, даже если произошла ошибка –
Проблема не в ошибке во время getTaskDetails, все детали задач загружаются должным образом. Я отредактировал свое оригинальное сообщение, пытаясь указать на это более четко. – Wujo