Angular 2可观察订阅箭头功能变得越来越大

时间:2017-02-10 10:33:36

标签: javascript angular typescript rxjs

我想知道在处理 http调用时是否有更好的方法来定义角度2可观察订阅回调函数而不违反Single responsibility principle当谈到嵌入式逻辑时,会导致丑陋的脏代码

我正在尝试使用函数变量而不是箭头函数来分隔回调逻辑,但我无法访问this和本地函数变量(示例中为state)。

updateState(state: string) {
  let proposition = new Proposition();
  proposition.id = this.id;
  proposition.state = state;
  this.propositionService.updateProposition(proposition).subscribe(
    (data) => {
    ....
    // instruction using local variable
    this.router.navigate(['/portfolio', state]);
    ....
  },
    .....
    // instrution using this
    (errors) => this.toastr.warning('Error.', 'ops !');
    .....}

1 个答案:

答案 0 :(得分:2)

有很多选择,都有好处和缺点。您应该根据具体情况选择具有最大上升空间和最少缺点的那个。

以下是一些选项(还有更多)

  1. 为箭头功能创建本地绑定。

    updateState(state: string) {
      const withNext = (data: { values: {}[] }) => {
        console.info(data.values);
        ....
        // instruction using local variable
        this.router.navigate(['/portfolio', state]);
        ....
      };
    
      const withError = error => {
        this.toastr.warning('Error.', error);
      }
    
      this.propositionService.updateProposition(proposition)
        .subscribe(withNext, withError);
    }
    

    这种方法的缺点是你需要在使用它们之前创建回调,因为分配不会被提升,并且你需要重新声明回调参数的类型推断,需要冗余地重述参数类型。 / p>

  2. 为了解决声明顺序问题,我们可以创建一个本地函数声明

    updateState(state: string) {
      this.propositionService.updateProposition(proposition)
        .subscribe(withNext, withError);
    
      const that = this;
    
      function withNext(data: { values: {}[] }) {
        console.info(data.values);
        ....
        // instruction using local variable
        that.router.navigate(['/portfolio', state]);
        ....
      }
    
      function withError(error) {
        that.toastr.warning('Error.', error);
      }
    }
    

    这种方法的缺点是你需要别名this,再次,我们失去了类型推断,必须求助于冗余,也许不正确地手动指定回调的参数类型。

  3. 如果observable只发出一个值,例如,如果它代表一个HTTP请求,我们可以使用toPromise并享受完整类型推断的清晰干净的代码,而不需要回调。

    async updateState(state: string) {
      try {
        const data = await this.propositionService.updateProposition(proposition)
          .toPromise();
        console.info(data.values);
        ....
        // instruction using local variable
        this.router.navigate(['/portfolio', state]);
        ....
      } catch (error) {
        this.toastr.warning('Error.', error);
      }
    }
    

    缺点是这种方法仅适用于最多发出单个值的可观察对象(例如HTTP请求)。

  4. state参数可供所有本地声明访问,无论方法如何,除非您希望将成功和失败逻辑提取到updateState方法之外的位置,否则不是因素。