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

Javascript 角度2:为什么在检索路由参数时使用switchMap?,javascript,angular,rxjs,observable,Javascript,Angular,Rxjs,Observable,我在看报纸 他们使用此代码检索路由器的参数'id',并使用它通过服务服务获得英雄: ngOnInit() { this.route.params .switchMap((params: Params) => this.service.getHero(+params['id'])) .subscribe((hero: Hero) => this.hero = hero); } 但我不太明白在上述代码中使用switchMap操作符的目的是什么 下面的代码不一样吗 n

我在看报纸

他们使用此代码检索路由器的参数
'id'
,并使用它通过
服务
服务获得英雄:

ngOnInit() {
  this.route.params
    .switchMap((params: Params) => this.service.getHero(+params['id']))
    .subscribe((hero: Hero) => this.hero = hero);
}
但我不太明白在上述代码中使用
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)
    });
}

switchMap
通常用于由某个前置“事件/流”触发的异步操作

例如,
flatMap
concatMap
的区别在于,一旦下一个触发器发出,当前异步操作将被取消并重新触发

在您的情况下,这意味着,一旦路由参数更改,您的hero服务将自动使用更改的参数再次调用,并且上一次调用将被取消,这样您就不会收到过时的数据

这对于可能需要超过200-300毫秒的搜索查询尤其有用,并且在用户键入时触发

下面的代码不一样吗

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)
    });
}
不。虽然在许多情况下,它的行为可能相同,但如果您想象以下场景:

  • 参数更改为“4”
  • getHero(4)
    (一个非常慢的请求)
  • 参数更改为“1”
  • getHero(1)
    (快速请求)
  • getHero(1)
    完成->英雄是“1”
  • getHero(4)
    completes->hero现在是“4”,但最后使用的参数是“1”

  • 在这种情况下,
    switchMap
    将丢弃
    getHero(4)
    -调用,因为一旦发生新的触发器,它就过时了。

    这一点解释得很好!一个问题是,是否必须返回内部订阅,例如,通过不使用箭头函数中的括号隐式返回,或者使用(params)=>{return….}
    ()=>{…}
    将默认返回类型void。使用switchMap,您必须返回一个可观察值。