Re-using an RxJS Observable to repeat an asynchronous call?

末鹿安然 提交于 2020-02-02 13:04:31

问题


How can an RxJS Observable emit a new value, if the underlying event stream doesn't emit a new value?

Given an Angular component which uses an async pipe to display a user's name;

export class MyComponent implements OnInit {

  public user$!: Observable<User>;

  constructor(private readonly ms: MyService)

  ngOnInit() {
    this.user$ = this.ms.getUser();
  }
}
<ng-container *ngIf="user$ | async as user; else empty">
  {{ user.name }}
</ng-container>

<ng-template #empty>
  No user here.
</ng-template>

...imagine some time passes and I want to try getting the user again by calling the asynchronous function this.ms.getUser(), how can I do this?

AFAIK, I cannot simply overwrite the Observable $captcha;

export class MyComponent implements OnInit {

  public user$!: Observable<User>;

  constructor(private readonly ms: MyService)

  ngOnInit() {
    this.user$ = this.ms.getUser();
  }

  getUserAgain() {
    // Wrong. This would be a new/different Observable.
    // The UI would not update.
    this.user$ = this.ms.getUser();
  }
}

The service MyService returns an Observable because it's just a thin wrapper around Angular's HttpClient.


回答1:


I'd recommend to use observables as much as possible and stay in a "reactive mind":

export class MyComponent {
  public refreshUser$: Subject<void> = new Subject();

  public user$!: Observable<User> = this.refreshUser$.pipe(
    startWith(undefined),
    switchMap(() => this.ms.getUser())
  );

  constructor(private readonly ms: MyService) {}

  public getUserAgain() {
    this.refreshUser$.next();
  }
}



回答2:


You could also use repeatWhen:

export class MyComponent implements OnInit {

  public user$!: Observable<User>;
  private repeat$ = new Subject()

  constructor(private readonly ms: MyService) {}

  ngOnInit() {
    this.user$ = this.ms.getUser().pipe(
      repeatWhen(() => repeat$)
    );
  }

  getUserAgain() {
    this.repeat$.next();
  }
}

https://stackblitz.com/edit/eoznkm



来源:https://stackoverflow.com/questions/59846027/re-using-an-rxjs-observable-to-repeat-an-asynchronous-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!