【问题标题】:Issue with chaining a number of RxJS Observable operators链接多个 RxJS Observable 运算符的问题
【发布时间】:2016-12-26 15:30:51
【问题描述】:

我正在尝试找到最干净的解决方案和操作符以链接可观察对象。

我的要求如下:

  1. 从路由参数中检索userAccountToken
  2. 使用 userAcccountToken 对后端进行 http 调用
  3. 再次使用userAcccountToken 对后端进行另一个http 调用
  4. 如果一切顺利,最后导航到一条路线(即/dashboard)。

我的angular 2组件如下:

import {Component, OnInit} from '@angular/core';
import {UserAccountService} from '../useraccount.service';
import {ActivatedRoute, Router} from '@angular/router';
import {SessionService} from '../../session/session.service';


@Component({
  templateUrl: 'useraccount-activation.component.html'
})
export class UserAccountActivationComponent implements OnInit {

  constructor(private userAccountService: UserAccountService,
              private sessionService: SessionService,
              private router: Router,
              private route: ActivatedRoute) {
  }

  ngOnInit() {
    this.route.params.map(params => params['userAccountToken'])//1.
      .switchMap(userAccountToken => this.userAccountService.activateAccount(userAccountToken))//2.
      .switchMap(() => this.sessionService.signinByUserAccountToken('???'))//3.
      .subscribe(() => this.router.navigate(['/dashboard']));//4.
  }
}

问题是我在两个地方都需要userAccountToken,但我需要订阅这两个 http 调用才能执行它们。

我可以在 2. 和 3. 之间执行另一个 this.route.params.map(...),但这似乎在重复我自己。

我可以使用 userAccountToken 实例变量在组件中引入状态,但我的函数会产生副作用。

什么是这个问题的干净解决方案?

编辑:如下代码:

  ngOnInit() {
    this.route.params.map(params => params['userAccountToken'])
      .mergeMap(userAccountToken => Observable.concatAll(
        this.userAccountService.activateAccount(userAccountToken),
        this.sessionService.signinByUserAccountToken(userAccountToken)
      ))
      .subscribe(() => this.router.navigate(['/dashboard']));
  }

产生以下错误:

__WEBPACK_IMPORTED_MODULE_4_rxjs_Observable__.Observable.concatAll is not a function

即使我已经导入了import 'rxjs/add/operator/concatAll';

edit 2:我收到上述错误的原因是我在Observable 上使用了concatAll,而不是在Observable 类型的实例/对象上...

【问题讨论】:

    标签: angular rxjs observable rxjs5


    【解决方案1】:

    您可以使用forkJoin 假设两个后端调用可以并行完成。如果你必须一个接一个地做,你可以使用嵌套的mergeMap

    const token$ = Rx.Observable.of('token')
    
    token$
      .mergeMap(token => Rx.Observable.forkJoin(
        Rx.Observable.of(token),
        Rx.Observable.of(token)
      ))
      .subscribe(val => console.log(val));
    <script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.11/dist/global/Rx.umd.js"></script>

    旁注:你真的应该将此功能导出到服务中;)

    【讨论】:

    • 谢谢塞巴斯蒂安。您能否提供我的ngOnInit 的样板?
    • 添加了一个可执行示例,展示如何使用 forkJoin。
    • 谢谢。我实际上需要concatAll,因为一个http 调用需要在另一个之前发出。我会更新我的代码。忍受我。
    • 我已经编辑了我的问题。我在导入 concatAll 运算符时遇到问题...您能解释一下如何让它在 angular2 的上下文中工作吗?
    • 这与您最初的问题无关。请善待并提出一个新问题并关闭/接受这个问题。请注意,导入还取决于您使用的 Rx 版本。
    猜你喜欢
    • 2017-07-22
    • 2017-04-18
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    • 2019-08-27
    • 2020-07-10
    • 2018-11-18
    • 1970-01-01
    相关资源
    最近更新 更多