RxJS可观察到:重复使用count然后使用notifier

时间:2018-08-28 09:11:19

标签: rxjs observable repeat

我有一个发射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

1 个答案:

答案 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个计数为止。