Как и ожидалось, следующий код выдает 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));
Почему это происходит? Как отсрочить выдачу ошибки?
Ошибка 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 секунды
Ха, это довольно умное использование редко известной пары операторов.