Мне нужно:
- отправка N запросов последовательно (для этого я использую concatMap)
- только если объект действителен (я расширяю карту concat с кодом проверки)
- остановка очереди при первой ошибке (ответом на ошибку сервера или отклонением проверки клиента)
Теперь код выглядит так:
ids = [{valid: true, id: 1}, {valid: true, id: 2}, {valid: true, id: 3}, {valid: false, id: 4}]
constructor(httpClient: HttpClient) {
from(this.ids)
.pipe(
map(obj => ({...obj, id: obj.id + 5})),
concatMap(obj => {
console.log('concat map');
if (obj.valid === false) {
return throwError('not valid');
} else {
return httpClient.get(`https://jsonplaceholder.typicode.com/todos/${obj.id}`);
}
})
)
.subscribe(
result => console.log('success', result),
result => console.log('error', result),
() => console.log('complete')
);
}
Вот стекаблитц: https://stackblitz.com/edit/angular-5vwbjg
Итак, я хочу не отправлять запрос, если объект недействителен. И я хочу обработать next
id из начального наблюдаемого, только если обработка предыдущего закончена. Поэтому я хочу, чтобы поток как:
- map + concatMap по первому идентификатору
- map + concatMap для второго идентификатора
- и еще больше больше ...
Я справился с этим только путем расширения кода concatMap. Возможно ли каким-то образом извлечь эту проверку другому оператору, работающему с конвейером, до concatMap
? Так что concatMap
тело будет проще.
Я попробовал оператор слияния, как:
mergeMap(obj => {
console.log(obj);
if (obj.valid === false) {
return throwError('not valid');
} else {
return of(obj);
}
}),
И я получил это в консоли:
Это неверный результат. Я ожидаю 3 запроса, а затем 1 ошибка.
Ожидаемый результат:
Также, возможно, есть более красивый способ описать функцию проверки в моем случае? Есть идеи? Без этого if
с 2 ветками.
Я думаю, что неправильно понял этот момент. from(this.ids)
все равно выдает значения. Не ждет concatMap
или карта или любой другой оператор. В тот момент, когда новое значение передается в from(this.ids)
(это будет до окончания concatMap
), оно обрабатывает всю цепочку: map
+ concatMap
. Что-то, что мне нужно, это как-то сказать, что rxjs обрабатывает 2-е излучаемое значение после того, как concatMap
завершил обработку 1-го. Затем он должен обработать 3-е испущенное значение, после того как concatMap
завершит обработку 2-го e c c.
Немного расширенный пример здесь: https://stackblitz.com/edit/angular-ovffm4?file=src/app/app.component.ts
Здесь у меня есть 2 проверки клиента и 1 ответ сервера.
Вот что я вижу в консоли:
map
first check true
second check 6
make request
map
first check true
second check 7
map
first check true
second check 8
map
first check true
second check 9
map
first check true
second check 10
map
first check false
success {userId: 1, id: 6, title: "qui ullam ratione quibusdam voluptatem quia omnis", completed: false}
make request
success {userId: 1, id: 7, title: "illo expedita consequatur quia in", completed: false}
complete
Как изменить мою наблюдаемую так, чтобы она выглядела так:
map
first check true
second check 6
make request
success {userId: 1, id: 6, title: "qui ullam ratione quibusdam voluptatem quia omnis", completed: false}
map
first check true
second check 7
make request
success {userId: 1, id: 7, title: "illo expedita consequatur quia in", completed: false}
map
first check true
second check 8
map
first check true
second check 9
map
first check true
second check 10
map
first check false
complete