У меня есть наблюдаемое, которое может выдать ошибку. Когда это бросает, я хочу повторно подписаться на это наблюдаемое и попробовать еще раз. Например, с оператором retry()
.
Чтобы проверить этот retry-logi c Мне нужно создать наблюдаемую проверку, которая будет выдавать ошибку в первые 2 раза, на которые она подписана, и только в 3-й время выдаст значение.
Я попробовал следующее:
import { Observable } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import { retry } from 'rxjs/operators';
// Setup for TestScheduler
function basicTestScheduler() {
return new TestScheduler((actual, expected) => {
expect(actual).toEqual(expected);
});
}
// The function we're going to test
function retryMultipleTimes(observable$) {
return observable$.pipe(retry(2));
}
describe('retryMultipleTimes()', () => {
it('retries twice when observable throws an error', () => {
basicTestScheduler().run(({ hot, cold, expectObservable }) => {
const observable$ = hot('--#--#--Y');
const expected = ' --------Y'; // This is what I want to get
const unexpected = ' --# '; // This is what I get instead
expectObservable(retryMultipleTimes(observable$)).toBe(expected);
});
});
});
Кажется, что при наблюдаемой hot()
он всегда повторно подписывается на тот же кадр, который вызвал ошибку, что приводит к немедленному выбрасыванию снова.
Я также пытался с cold()
наблюдаемым, в этом случае я получаю ------#
- то есть, при каждой повторной попытке наблюдаемое начинается снова с самого начала, что приводит к --#
, --#
, --#
- никогда не достигать --Y
.
Похоже, что с Rx JS TestScheduler такого способа не сделать. Или, может быть, есть?
Если hot()
и cold()
наблюдатели-создатели не справляются с задачей, возможно, я могу создать свою собственную ... но как?
I также попытался добавить небольшую задержку между повторными попытками, поэтому я не стал бы сразу же повторно подписываться на текущий кадр, реализовав retry-logi c, используя retryWhen
:
function retryMultipleTimes(observable$) {
return observable$.pipe(
retryWhen(errors => errors.pipe(
delayWhen(() => timer(2)), // wait 2 frames before each retry
take(2), // do maximum of 2 retries
concat(throwError('error')), // finish with error when no success after 2 retries
)),
);
}
Но это тоже не сработало , Похоже, повторная подписка по-прежнему происходит в том же кадре, что и раньше.
Как я могу пройти этот тест?