如何处理仅在验证成功后才返回Observable的函数?

时间:2019-11-05 20:11:24

标签: angular typescript rxjs

我希望这不是基于观点的。我在想可能存在一种我不知道的最佳实践,或者一种我不知道的机制,或者我至少希望对可能的解决方案的利弊有更好的了解。

说我在名为ImportService的Angular服务中具有这些功能,该服务处理围绕导入的所有逻辑:

  /** Only call this after calling validateImportFile and getting back true! */
  new(file: File): Observable<ImportResource> { 
    return this.apiService.importCreate(file);
  }

  validateImportFile(file: File): Boolean {
    //some validation logic
  }

如果TypeScript更像Java,我宁愿做更多类似的事情:

  new(file: File): Observable<ImportResource> throws ImportValidationError {
    if(this.validateImportFile(file)) {
      return this.apiService.importCreate(file);
    } else {
      throw new ImportValidationError("Your file is bad and you should feel bad");
    }
  }

  private validateImportFile(file: File): Boolean {
    //some validation logic
  }

以便呼叫者可以做更多类似的事情

try {
  importService.new(aFile).subscribe( importInfo => {
    //Display stuff about importInfo
  }, error => {
    //There was some kind of http error
  });
} catch (ImportValidationError e) {
    //There was something wrong with the file itself
}

主要优点是

  • new()将始终进行验证,而呼叫者不必知道/记住要先调用验证
  • new()的签名清楚地告诉调用者,他们必须处理验证失败
  • new()的调用者可以轻松地区分验证失败案例和其他失败案例

但是据我所读,以这种方式抛出错误现在是TypeScript中的一种反模式,因为您不能在签名中放置“ throws”声明来提醒调用者期望它,并且编译器不会期望呼叫者能够抓住它,因此所有这些好处都将丢失。

如果我返回一个可观察到的错误,我认为调用者不会知道会为验证失败专门遇到某种类型的错误。

另一种选择是返回一个包装对象,该对象指示是否存在错误,并且仅在成功时才包含可观察对象,但这似乎很杂乱无章,我不得不怀疑是否有更好的方法。有吗?

1 个答案:

答案 0 :(得分:0)

功能性反应式编程确实可以在全新的思维方式下工作,在FRP中,您的代码可以像下面这样简单。使用rxjs中的throwError

const createNew=(file)=>
    this.validateImportFile(file)?
        throwError(new ImportValidationError("Your file is bad and you should feel bad")):
        this.apiService.importCreate(file);

用法

   createNew(yourfile).subscribe(()=>console.log('sucess'),err=>console.log(error))