在 Angular 中使用 RxJS 与条件/组合订阅

Using RxJS in Angular with conditional / combined subscriptions

在我的 Angular 应用程序中,我有一个 API 服务,它包含两种方法:

addComment(id: string, comment: string): Observable<any> {
    return this.http.post(`api/${encodeURIComponent(id)}/comment`, { comment }).pipe(
      map(this.apiUtils.extractData)
    );
  }


closeAccount(id: string): Observable<any> {
    return this.http.post(`api/${encodeURIComponent(id)}/closeaccount`, {}).pipe(
      map(this.apiUtils.extractData)
    );
}

现在在我的应用程序中,我有一个组件,我可以在其中关闭用户帐户,如果添加了评论,我希望在关闭帐户之前添加评论,但这是有条件的,有时用户不需要在关闭帐户之前添加评论。在我的组件文件中,我为此创建了一个方法,但我有点卡住了……这是我的组件代码,我从表单中收集用户数据和评论。如果我们有评论,我们会调用 api 来添加评论,当评论解决时,我会调用 API 来关闭帐户。如果没有提交评论,我只需调用 api 关闭帐户。这还可以,但很难eloquent!请注意我已经减少了代码以提高可读性。

constructor(private formBuilder: FormBuilder,
            public apiService: ApiService) {}

// i have omitted the code where I create my form and validation

closeAccount(): void {
    // get values from my form
    const id = this.closeAccountForm.controls.id.value;
    const comment = this.closeAccountForm.controls.closeAccountComment.value; 

    if (comment) {
        this.apiService.addComment(id, comment).subscribe(() => {
            this.apiService.closeAccount(id).subscribe(() => {
                // now do something
            });
        })
    } else {  
        this.apiService.closeAccount(id).subscribe(() => {
            // now do something
        });
    }
}

我想知道是否可以减少代码并防止重复调用closeAccount 方法。 RxJS 是否为我提供了一种在方法中应用条件逻辑的方法?我上面的东西可以用但是很丑!

我目前正在阅读文档,但有时人们可以更快地提供答案。如果我找到 answer/solution,我将在此处提供。提前谢谢了。如果我的措辞不好,请指出,我会修改我的问题。

如果请求的顺序无关紧要,您可以从 if 子句中删除调用并删除 else。

closeAccount(): void {
    ... 

    if (comment) {
        this.apiService.addComment(id, comment).subscribe(); 
    } 

    this.apiService.closeAccount(id).subscribe(() => {
       // now do something
    });
}

如果顺序很重要,您可以根据条件为请求设置可观察对象,然后对结果调用订阅。

 closeAccount(): void {
    ...
    const request = comment 
      ?  this.apiService.addComment(id, comment).pipe(
           switchMap(_ => this.apiService.closeAccount(id))
         ) 
      : this.apiService.closeAccount(id);

    request.subscribe(() => {
       // now do something
    });
}

干杯

试试这个:

const preCloseAction = comment ? this.apiService.addComment(...) : of(null);

preCloseAction.pipe(
  switchMap(() => this.apiService.closeAccount(id))
).subscribe(() => {
  // now do something
})

或者,如果在 closeAccount 调用期间评论的结果无关紧要

concat(
  !comment ? EMPTY : this.apiService.addComment(...),
  this.apiService.closeAccount(id)
).pipe(last()).subscribe(() => {
  // now do something
})