Как отложить throwError с помощью RxJS?

Как и ожидалось, следующий код выдает 42 через 5 секунд:

const valueObservable = of(42).pipe(delay(5000));
valueObservable.subscribe((value) => console.info(value));

Однако эта версия бросает ошибки сразу при подписке:

const throwingObservable = throwError(new Error('My Error')).pipe(delay(5000));
throwingObservable.subscribe((value) => console.info(value), (error) => console.error(error));

Почему это происходит? Как отсрочить выдачу ошибки?

Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
Promise v/s Observable в Angular
Promise v/s Observable в Angular
В системах Push производитель определяет, когда отправить данные потребителю. Потребитель не знает, когда он получит эти данные.
Подсказка RxJS [filter, skipWhile]
Подсказка RxJS [filter, skipWhile]
Эта подсказка описывает разницу между операторами filter и skipWhile из библиотеки RxJS .
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
13
0
3 071
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Ошибка Rxjs является исключением, она немедленно останавливает поток и позволяет вам отреагировать на что-то неожиданное. Я думаю, у вас нет другого способа манипулировать потоком throwError, кроме как с помощью catchError

Решение 1. Управляйте потоком, прежде чем выдавать ошибку.

const throwingObservable = throwError(new Error('My Error'));
timer(5000).pipe(mergeMap(e => throwingObservable))
  .subscribe((value) => console.info(value), (error) => console.error(error));

Решение 2. Перехватите ошибку, задержите поток, а затем снова отправьте его

throwingObservable.pipe(
  // We catch the error, we delay by adding timer stream, then we mergeMap to the error.
  catchError(e => timer(1000).pipe(mergeMap(t => throwError(e)))
)).subscribe(console.info, console.error);

Вы можете увидеть это в действии

Я нашел (IMO) более простой способ отсрочить появление ошибки:

const throwingObservable = of(42).pipe(
    delay(5000),
    switchMap(() => throwError(new Error('My Error')))
);
throwingObservable.subscribe(
    value => console.info(value),
    error => console.error(error)
);

У меня была аналогичная проблема, и я нашел эту проблему на github: https://github.com/Reactive-Extensions/RxJS/issues/648

Обновлено до моего варианта использования, это будет примерно так:

const throwingObservable = throwError(new Error('My Error'))
  .pipe(
    materialize(),
    delay(4000),
    dematerialize()
  );

throwingObservable.subscribe(console.info, console.error);

Выдает с задержкой в ​​4 секунды

Ха, это довольно умное использование редко известной пары операторов.

Lazar Ljubenović 17.01.2022 13:31

Другие вопросы по теме