Angular / RxJS取消订阅先前的请求

时间:2020-01-14 18:15:14

标签: angular rxjs

我正在尝试找到一种更有效/类似于rxjs的方式来实现这一目标。下面的代码有效,但是必须有更好的方法。

ngOnInit() {
  this.activatedRoute.params.subscribe(({ bookId }) => {
    this.characters$ && this.characters$.unsubscribe();

    this.characters$ = this.fetchCharactersByBook(bookId)
      .subscribe(characters => this.characters = characters);
  });
}

基本上,我只是在听路由参数的更改,并订阅由Characters来获取bookId的请求。随着对路由参数的每次更改,我都需要首先从上一个请求中退订以获取字符。

是否有更好,更优雅的方法来实现这一目标?

有时RxJS让所有操作员都感到头疼。非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您实际上不需要unsubscribe。您可以使用switchMap运算符将params对象转换为字符列表。而且,您应该通过使用async管道将其在模板中展开来强制性地管理预订。

创建可观察的角色。

this.characters$ = this.activatedRoute.params
  .pipe(switchMap(parms => this.fetchCharactersByBook(parms.bookId));

创建observable后,请使用异步管道将characters的模板引用替换为(characters$ | async),以对其进行解包。该组件将在拆解过程中处理characters$可观察到的内容。\

答案 1 :(得分:1)

switchMap可用于从外部可观察到内部可观察的切换,并具有在下一个值发出时取消订阅到内部可观察的优点。取消订阅将取消之前仍待处理的Http请求。

您可以在模板中使用*ngIf="o$ | async as o"语法,以避免必须订阅并将变量分配给本地属性。 as o将声明一个带有发射值的模板变量。

如果要在同一模板中多次使用o$ | async,而又不发出多个Http请求,则可以使用shareReplay

@Component({
   ...
   template: `<ng-container *ngIf="characters$ | async as characters">
      {{characters | json}}
   </ng-container>`
})
export class ExampleComponent {
   characters$: Observable<Character[]>;

   public ngOnInit() {
      this.characters$ = this.activatedRoute.params.pipe(
         pluck('bookId'),
         switchMap(bookId => this.fetchCharactersByBook(bookId)),
         shareReplay(1)
      );
   }
}
相关问题