首页 > 解决方案 > 如何处理仅在验证成功时才应返回 Observable 的函数?

问题描述

我希望这不是太基于意见。我在想可能有一个我不知道的最佳实践,或者一个我不知道的机制,或者我至少希望更好地了解可能的解决方案的优缺点。

假设我在一个名为 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
}

主要好处是

但是从我读到的以这种方式抛出错误现在是 TypeScript 中的一种反模式,因为你不能在签名中放置“抛出”声明来提醒调用者期待它,而编译器不会期望调用者能抓住它,所以所有这些好处都失去了。

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

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

标签: angulartypescriptrxjs

解决方案


函数式反应式编程确实适用于全新的不同思维方式,在 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))

推荐阅读