我有一个发射Either = Success | Failure
的Observable:
import { Observable } from 'rxjs';
type Success = { type: 'success' };
type Failure = { type: 'failure' };
type Either = Success | Failure;
const either$ = new Observable<Either>(observer => {
console.log('subscribe');
observer.next({ type: 'failure' });
observer.complete();
return () => {
console.log('unsubscribe');
};
});
我想允许用户在Observable完成且最后一个值为Failure
时“重试” observable。
(retry{,When}
运算符在这里无济于事,因为它们在error
通道上处理错误。因此,我认为我们应该考虑使用repeat
。)< / p>
我要:
n
次,直到最后一个值不是Failure
。repeat$
)时,请再次重复观察者。例如:
// subscribe
// next { type: 'failure' }
// unsubscribe
// retry 2 times:
// subscribe
// next { type: 'failure' }
// unsubscribe
// subscribe
// next { type: 'failure' }
// unsubscribe
// now, wait for repeat notifications…
// on retry notification:
// subscribe
// next { type: 'failure' }
// unsubscribe
答案 0 :(得分:0)
我想不出更简单的方法,但是代码可以满足您的要求。
请参见https://stackblitz.com/edit/typescript-yqcejk
defer(() => {
let retries = 0;
const source = new BehaviorSubject(null);
return merge(source, repeat$.pipe(filter(() => retries <= MAX_RETRIES)))
.pipe(
concatMapTo(either$),
tap(value => {
const action = value as Either;
if (action.type === 'failure') {
if (retries < MAX_RETRIES) {
retries += 1;
source.next(null);
}
} else {
retries = 0;
}
})
)
}).subscribe(console.log);
我不得不手动计算重试次数。
该代码有两个事件源source
用于自动重试,事件repeat$
用于用户重试。所有事件都使用either$
映射到concatMapTo
。作为副作用,我们next()
重试或不做任何等待用户重试的操作。
使用filter(() => retries >= MAX_RETRIES)
禁止用户重试,直到达到MAX_RETRIES
个计数为止。