【问题标题】:Looking for an RxJS operator寻找 RxJS 运算符
【发布时间】:2019-01-27 15:48:24
【问题描述】:

我正在使用 Angular 服务来允许用户上传文件。

服务的实现正在运行;我的问题是关于 RxJS 及其可管道操作符,但这里是服务签名以防万一:

askUserForFile(): Observable<File>;
toBase64(file: File): Observable<string>;
isFileValid(file: File, configuration?: { size?: number, extensions?: string | string[] }): boolean;

对该服务的调用如下:

  this.fileService
    .askUserForFile()
    .pipe(
      // this is the operator I'm looking for 
      unknownOperator(file => this.fileService.isFileValid(file, { extensions: ['txt'] }))
      mergeMap(file => {
        fichier.filename = file.name;
        return this.fileService.toBase64(file);
      }))
    .subscribe(base64 => {
      fichier.base64 = base64;
      // Rest of my code
    }, error => {/* error handling */});

我想找到一个运算符来代替unknownOperator,如果不满足条件,它将引发错误。

我试过了

  • filter : 如果条件不满足,代码在它之后停止,
  • map :即使throwError 抛出错误,代码也会继续

我考虑过使用以下管道

.pipe(
  map(...),
  catchError(...),
  mergeMap(...)
)

我认为这可能可行,但我想(如果可能)找到一个缩短此管道的操作员。

有可能吗?如果没有,有更好的管道吗?

【问题讨论】:

  • 我只需在mergeMap 中调用isValidFile,如果它返回一个错误值,要么返回一个throwError observable,要么只返回一个错误throw
  • @cartant 它也可以,谢谢,但我希望能够为此使用运算符,我认为这样会更干净

标签: angular typescript rxjs rxjs-pipeable-operators


【解决方案1】:

您可以只使用map,但您必须使用throw 关键字抛出异常,而不是返回throwError,因为这只会创建另一个Observable。您也可以使用mergeMap,然后使用throwError,但这可能过于复杂。

map(val => {
  if (val === 42) {
    throw new Error(`It's broken`);
  }
  return val;
})

单线:

mergeMap(val => val === 42 ? throwError(new Error(`It's broken`)) : of(val))

【讨论】:

  • 谢谢,它有效,但它删除了单行条件;这是唯一的方法吗?
  • 那用mergeMap可能更方便,看我的更新
  • 它也可以,但是由于 linter 的存在会变得很糟糕:mergeMap(file =&gt; (this.fileService.isFileValid(file, { extensions: ['txt'] }) ? of(file) : throwError('Error ...')) as Observable&lt;File&gt;) ...所以除了类似的解决方法之外,真的没有内置的运算符吗?
  • 嗯,你可以把它放到自定义运算符中。
  • 我从来没有深入到 RxJS,我不知道你能做到这一点!谢谢你的提醒,我想我会这样做
猜你喜欢
  • 1970-01-01
  • 2018-07-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 2017-04-28
  • 2020-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多