Angular 2:为什么在检索路由参数时使用switchMap?

And*_*rea 57 javascript observable rxjs angular

我正在阅读有关路由和导航的角度指南.

他们使用此代码检索路由器的参数'id'并使用它来获取service服务的英雄:

ngOnInit() {
  this.route.params
    .switchMap((params: Params) => this.service.getHero(+params['id']))
    .subscribe((hero: Hero) => this.hero = hero);
}
Run Code Online (Sandbox Code Playgroud)

但我不太清楚switchMap在上面的代码中使用运算符的目的是什么.

以下代码不一样?

ngOnInit() {
  this.route.params
    // NOTE: I do not use switchMap here, but subscribe directly
    .subscribe((params: Params) => {
      this.service.getHero(+params['id']).then(hero => this.hero = hero)
    });
}
Run Code Online (Sandbox Code Playgroud)

ols*_*lsn 96

switchMap 当你有一些异步操作被一些前置的"事件/流"触发时,通常会使用它.

与例如flatMap或之后的区别concatMap在于,一旦下一个触发器发出,就取消并重新触发当前的异步操作.

在您的情况下,这意味着,一旦路由参数更改,您的英雄服务将自动再次使用更改的参数调用,并且前一个呼叫被取消,因此您将不会收到过时的数据.

这对于搜索查询尤其有用,搜索查询可能需要200-300ms,并且在用户键入时会触发.

以下代码不一样?

不会.虽然在许多情况下它的行为可能相同,但如果您想象以下情况:

  1. param变为"4"
  2. getHero(4) (一个非常慢的请求)
  3. 参数更改为"1"
  4. getHero(1) (快速请求)
  5. getHero(1) 完成 - >英雄是"1"
  6. getHero(4) 完成 - >英雄现在是"4"但最后使用的参数是"1"

在这种情况下switchMap,只要丢弃getHero(4)-call,因为一旦发生新的触发,它就会过时.