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

Posted

技术标签:

【中文标题】Angular 2:为啥在检索路由参数时使用 switchMap?【英文标题】:Angular 2: why use switchMap when retrieving route params?Angular 2:为什么在检索路由参数时使用 switchMap? 【发布时间】:2017-07-28 01:33:11 【问题描述】:

我正在阅读Angular Guide about Routing & Navigation。

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

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)
    );

【问题讨论】:

【参考方案1】:

switchMap 通常在您有一些由一些前置“事件/流”触发的异步操作时使用。

与例如的区别flatMapconcatMap 是,一旦下一个触发器发出,当前的异步操作就会被取消并重新触发。

在您的情况下,这意味着,一旦路由参数更改,您的 hero-service 会自动使用更改的参数再次调用,并且之前的调用被取消,因此您不会收到过时的数据。

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

下面的代码会不会一样?

没有。虽然在许多情况下它的行为可能相同,但如果您想象以下场景:

    参数更改为“4” getHero(4)(一个很慢的请求) 参数更改为“1” getHero(1)(快速请求) getHero(1) 完成 -> hero is "1" getHero(4) 完成 -> hero 现在是“4”,但最后使用的参数是“1”

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

【讨论】:

这很好解释!一个问题,是否必须返回内部订阅,例如通过不使用箭头函数中的括号或使用 (params)=> return .... 来隐式地 () => ... 默认返回类型 void。使用 switchMap 你必须返回一个 Observable。

以上是关于Angular 2:为啥在检索路由参数时使用 switchMap?的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2:如何将路由参数传递给子路由?

li 在 Angular 中路由到不同的 html 页面时不会消失,为啥?

为啥在尝试使用 Angular 检索数据库信息时出现错误 415?

Angular 8 应用程序在使用 router.navigate 时无法检索表单字段值

部分静态路由参数 angular 2

在 Angular 中首次渲染时,路由查询参数为空