[英]RxJS Observable: repeat using count and then using notifier
I have an Observable that emits Either = Success | Failure
我有一个Observable发出Either = Success | Failure
Either = Success | Failure
: Either = Success | Failure
:
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');
};
});
I want to allow the user to "retry" the observable when the Observable completes and the last value was Failure
. 我想允许用户在Observable完成并且最后一个值为Failure
时“重试” observable。
(The retry{,When}
operators do not help here because they work with errors on the error
channel. For this reason, I believe we should think in terms of repeat
instead.) ( retry{,When}
运算符在这里无济于事,因为它们在error
通道上处理error
。因此,我相信我们应该考虑repeat
。
I want to: 我想要:
n
times until the last value is not Failure
. 重复Observable n
次,直到最后一个值不是Failure
。 repeat$
) emits, repeat the observable again. 当发出一个重复通知者observable( repeat$
)时,请再次重复该observable。 For example: 例如:
// 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
I couldn't come up with something simpler, but the code does what you want. 我无法提出更简单的方法,但是代码可以满足您的要求。
See https://stackblitz.com/edit/typescript-yqcejk 参见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);
I had to manually count retries. 我不得不手动计算重试次数。
The code has two sources of events source
for automatic retries and repeat$
for user retries. 该代码有两个事件source
,它们分别是自动重试的事件source
和repeat$
的用户重试源。 All events are mapped to either$
using concatMapTo
. 所有的事件映射到either$
使用concatMapTo
。 As a side-effect we either next()
to retry or do nothing waiting for user to retry. 作为副作用,我们要么next()
重试,要么不做任何等待用户重试的操作。
User retries are suppressed using filter(() => retries >= MAX_RETRIES)
until MAX_RETRIES
count is reached. 使用filter(() => retries >= MAX_RETRIES)
抑制用户重试,直到达到MAX_RETRIES
计数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.