Jodły w całości Jestem nowy w rxswift, więc myślę, że odpowiedź jest oczywista, ale w tej chwili nie mogę znaleźć rozwiązania samodzielnie.Właściwe użycie RxSwift do żądania łańcuchów, flatMap lub czegoś innego?
Mam dwie funkcje:
func downloadAllTasks() -> Observable<[Task]>
func getTaskDetails(taskId: Int64) -> Observable<TaskDetails>
Pierwszy pobiera listę Task obiektów za pomocą żądania sieciowego, drugi pobierając szczegóły zadania dla sepcific zadania (za pomocą jego id)
Czego chcę od Osiągnięcie polega na pobraniu wszystkich zadań, a następnie dla każdego zadania chcę pobrać jego szczegóły i zasubskrybować zdarzenie uruchamiane, gdy wszystkie szczegóły zadań są gotowe.
Sądzę, że powinienem zapisać się do Observable < [TaskDetails]>, ale nie wiem jak to zrobić.
downloadAllTasks()
.flatMap{
... // flatMap? something else?
}
.subscribe(
onNext: { details in
print("tasks details: \(details.map{$0.name})")
})
.addDisposableTo(disposeBag)
// EDIT
Dzięki Silvan Mosberger odpowiedzi jestem znacznie bliżej do rozwiązania. Pozostał tylko jeden problem. Teraz mam coś takiego:
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)
wyjście jest
$$$ task details array debug -> subscribed
$$$ single task details downloaded
$$$ single task details downloaded
$$$ single task details downloaded
Istnieją 3 Zadania dostępne tak jak można se wszystkie z nich są pobierane prawidłowo jednak z jakiegoś powodu wyniku ToArray() - (Observable<[TaskDetails]>
) nie generuje "onNext", gdy wszystkie szczegóły zadania są gotowe.
// Edit raz
Ok, Dodaję uproszczoną wersję funkcji zapewniających obserwable, może to pomoże coś
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()
}
}
Nice and clean wyjaśnienie, dziękuję. I prawie działa tak, jak chcę. Prawie, ponieważ mam problem z ostatnią częścią - toArray(). Bez tej części subskrybent jest prawidłowo powiadamiany o zdarzeniach pobierania szczegółów zadań. Z toArray oczekiwałbym, że otrzymam powiadomienie w onNext subskrybenta po pobraniu wszystkich szczegółów zadania, ale onNext nie jest w ogóle wywoływany. Czy widzisz, co może być problemem? – Wujo
@Wujo Gdy pobieranie pojedynczego zadania zostanie napotkane podczas błędu, ostateczny błąd "Observable" spowoduje błąd. Powinieneś być w stanie to sprawdzić za pomocą '.debug()' przed '.toArray()'. Edytowałem moją odpowiedź, jeśli chcesz ją ukończyć, mimo że wystąpił błąd –
Problem nie jest błędny podczas getTaskDetails, wszystkie szczegóły zadań są pobierane poprawnie. Zmieniłem swój oryginalny post, próbując wskazać to dokładniej. – Wujo