Ну, кроме того факта, что возвращение массива в результате Observable выглядит немного странно, это как бы я это сделать:
getExercises(programKey: string): Observable<Array<Exercise>> {
// ... stuff here ...
return programExercises
// assuming that programExercisesSnapshot is an array or can be easily converted to it
.flatMap(programExercisesSnapshot => Observable
.from(programExercisesSnapshot)
.flatMap(programExercise => this.getExercise(programExercise.ExerciseKey))
.bufferCount(programExercisesSnapshot.length));
Теперь давайте посмотрим, как это должно работать. Начнем с внутренней вещи.
- мы генерируем наблюдаемый из массива
programExercisesSnapshot
, который затем испускает элементы один за другим;
- мы улавливаем эти элементы и заменяем их в потоке с результатами наблюдений, возвращаемыми
this.getExercise(programExercise.ExerciseKey)
звонками с использованием flatMap()
;
bufferCount()
собирает programExercisesSnapshot.length
элементов в один массив и испускает их в результате.
Таким образом, весь этот трубопровод излучает массивы результатов вызовов this.getExercise()
.
Теперь внешняя вещь делает следующее:
- он принимает партии, испускаемые
programExercises
;
- заменяет их результатами (например, массивами), испускаемыми ранее описанными наблюдаемыми;
- и испускает эти результаты как свои собственные.
Прибыль! :)
Еще одна вещь, которую вы пропустили в своем оригинальном решении, - это очистка. Когда вы делаете programExercises.subscribe()
, вам также необходимо отказаться от подписки на нее вручную. Выполнение, как я предложил, устраняет необходимость в нем - rxjs позаботится об этом для вас.
Также, как я сказал в начале, возвращение Массив в наблюдаемых выглядит несколько странно. Надеюсь, у вас есть все основания для этого. :) В противном случае вы можете подумать о том, чтобы преобразовать это в наблюдаемые излучающие элементы один за другим.
ОБНОВЛЕНО.
Поскольку автор признался :), что массивы не нужны здесь другое решение, более простой и элегантный:
getExercises(programKey: string): Observable<Exercise> {
// ... stuff here ...
return programExercises
// assuming that programExercisesSnapshot is an array or can be easily converted to it
.flatMap(programExercisesSnapshot => Observable.from(programExercisesSnapshot))
.flatMap(programExercise => this.getExercise(programExercise.ExerciseKey));
Это красиво, спасибо так много! Rx может показаться почти как магия для непосвященных :) У меня нет веской причины возвращать массив в наблюдаемом. Я просто хочу вернуть список упражнений. Можете ли вы объяснить, почему Observable плохой? –
user1202032
@ user1202032, я бы не сказал, что это совсем плохо, это просто не лучшая практика для создания коллекций коллекций, что по сути является тем, что вы делаете. Вы просто пытаетесь сделать работу наблюдаемого с этим массивом. Почему бы не заставить Observable выполнять свою работу? :) Я обновлю ответ. –