#javascript #typescript #rxjs
#javascript #машинописный текст #rxjs
Вопрос:
У меня есть массив наблюдаемых, для простоты я создаю образец массива ниже
dataList = of([Array(20).fill(0).map((_r,k) => k)]); // of([1, 2, 3, 4, ..., 20])
Приведенное выше генерирует Observable
объект, который генерирует массив. В реальном коде эти данные извлекаются с помощью http-вызова
Теперь я пытаюсь добиться этого;
- Для каждого из этого списка создайте новый
Observable
, который выдает каждый элемент за другим
Этого я добиваюсь с помощью flatMap
оператора, как показано ниже
flatMap(item => item )
- Сделайте http-запрос. Для этого я использую
mergeMap(i => this.myService.save(i))
- Убедитесь, что каждый запрос запускается только после последнего запроса
вот тут-то у меня и возникла проблема
Из этой демонстрации я высмеял http
запрос на возврат через 1 секунду. С консоли все это возвращается через 1 секунду. Но я бы хотел, чтобы это было что-то вроде
http /1
http / 2 (отложено доhttp/1
завершения)
http / 3 (отложено доhttp/2
завершения)
http / 4 (отложено доhttp/3
завершения)
…
http / 20 (отложено доhttp/19
завершения)
Комментарии:
1. Используйте
concatMap
вместоmergeMap
. Вы также можете использоватьfrom
вместоof()
в этом случае и избавиться отflatMap(item => item)
2. @мартин
concatMap
сработал! Потому что изменениеof
наfrom
может быть не тем, что я ищу, но изменениеmergeMap
наconcatMap
сделало именно то, что я искал
Ответ №1:
Вероятно, это то, что вам нужно:
of(Array(20).keys()).pipe(
mergeMap(list => list),
concatMap(i => this.myService.save(i))
)
Ниже приведен еще один способ сделать то же самое, хотя это может сделать идиоматическую проблему немного более понятной:
of(Array(20).keys()).pipe(
mergeMap(list => list.map(
i => this.myService.save(i)
)),
concatAll()
)
concatMap
и concatAll
храните запросы буферизации (противодавления) в массиве, поэтому немного странно превращать массив в поток, а затем сразу же превращать этот поток обратно в массив.
Следующий подход пропускает этот шаг, сохраняя ваш массив целым и используя статический concat
оператор (который принимает массив наблюдаемых вместо потока).
of(Array(20).keys()).pipe(
map(list => list.map(
i => this.myService.save(i))
),
switchMap(httpList => concat(...httpList))
)
которые могут быть объединены в один оператор следующим образом:
of(Array(20).keys()).pipe(
switchMap(list =>
concat(...list.map(
i => this.myService.save(i)
))
),
)