【问题标题】:Angular 2 observable subscribe arrow functions getting big and dirtyAngular 2 observable subscribe 箭头函数变得又大又脏
【发布时间】:2017-06-28 16:06:45
【问题描述】:

我想知道在处理http调用时是否有更好的方法来定义angular 2 observable subscribe回调函数而不违反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 !');
    .....}

【问题讨论】:

  • 我真的不明白你想在这里做什么。你想去订阅中的其他路线吗?您想在 router.navigate 之前定义操作吗?你能澄清一下吗?
  • 实际上“=>”有你当前组件的 this 但是当你使用函数变量时,你的组件的 this 有新的 this 所以你不能得到你的局部变量。(数据)=>这是Angular 2 承诺,所以你必须使用 lemda 表达式。
  • @ER.SHASHITIWARI 我经历过,我想问如何找到一个好的替代方案
  • @ZanattMan 导航到其他根目录或其他内容,这不是问题。这只是一个示例,表明回调需要访问某些局部变量。我的问题是如何将回调逻辑分离到独立函数以拥有更简洁的代码而不是嵌入复杂的函数

标签: javascript angular typescript rxjs


【解决方案1】:

有很多选择,都有优点和缺点。您应该根据具体情况选择优点最多和缺点最少的一种。

这里有几个选项(还有更多)

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

    这种方法的缺点是您需要在使用它们之前创建回调,因为分配不会被提升,而且您丢失了回调参数的类型推断,需要重复地重新声明参数类型。

  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 请求)。

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

【讨论】:

    猜你喜欢
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多