使用 rxjs 动态添加验证可观察对象

Dynamically add validation observables using rxjs

我正在尝试编写一个可观察的验证任务。我有 2 个要按顺序处理的可观察对象,frontEndValidatebackEndValidate。如果抛出错误,管道应该停止。当我单击 validate 按钮时,通过在 validate().

中调用 next(),将在运行时发出这 2 个 observables

在管道中,我检查发出的 obervables 是否有效,如果有效则继续,否则抛出错误。

如果这 2 个 observable 发出 of({ valid: true}),则此管道工作正常。但是如果它发出 of({valid:false}),我的 validationAction$ 就会死掉,validate 按钮将不起作用。

我也不能使用 catchError 来保持管道活动,因为无论可观察对象处于什么状态,验证都会继续。

简而言之,我希望我的管道像这样运行并且仍然存在。

  1. 大小写有效,有效 => from([true,true])
  2. 大小写有效,无效 => from([true, false])
  3. 大小写无效 => 来自([false])

谢谢。

流水线

private validationSubject = new Subject<Observable<any>>();
validationAction$ = this.validationSubject.asObservable().pipe(
    concatMap((item) =>
        from(item)
            .pipe(
                map((result) => {
                    console.log("result", result);
                    if (!result.valid) throw new Error();
                    return result
                }),
            )
    ),
);

点击

validate() {
    this.validationSubject.next(this.frontEndValidate());
    this.validationSubject.next(this.backEndValidate());
}

2 个可观察对象

/* Front-end validation */
/** */
frontEndValidate(): Observable < any > {
    // Validation goes here

    return of({ valid: true, name: 'frontend', msg: 'Passed' }).pipe(
        tap(() => {
            console.log('frontend validation...starts');
        }),
        delay(3000), // mimic delay
        tap(() => {
            console.log('frontend validation...finished')
        }),
    );
}

/* Back-end validation */
/** */
backEndValidate(): Observable < any > {
    // Validation goes here 

    return of({ valid: true, name: 'backend', msg: 'Passed' }).pipe(
        tap(() => {
            console.log('backend validation...starts');
        }),
        delay(3000), // mimic delay
        tap(() => {
            console.log('backend validation...finished')
        }),
    );
}

这样的事情怎么样:

  validate() {
    const result$ = combineLatest([
      this.frontEndValidate(),
      this.backEndValidate(),
    ])
      .pipe(
        tap(([frontEndResult, backEndResult]) => {
          // Do whatever else here
        })
      );

    result$.subscribe(x => console.log('Result: ', JSON.stringify(x)));
  }

那你就不需要主题了。只需使用 combineLatest 组合两个结果并确保其后的代码在继续之前等待两者完成。

结果发出一个数组,其中包含验证方法中定义的两个对象。要只发出一个包含布尔值的数组,试试这个:

  validate() {
    const result$ = combineLatest([
      this.frontEndValidate(),
      this.backEndValidate(),
    ]).pipe(
      map(([frontEndResult, backEndResult]) => 
        ([frontEndResult.valid, backEndResult.valid])
      )
    );

    result$.subscribe((x) => console.log('Result: ', JSON.stringify(x)));
  }

工作示例:https://stackblitz.com/edit/angular-rxjs-validation-deborahk