Observable in observable with conditions - Angular 10

Obervable in obervable with conditions - Angular 10

我想在表格中添加一本书。

用户手动输入作者姓名。当用户提交表单时,它应该首先检查作者是否存在:

我想我可以让它工作:

formSubmit() {
  this.authorService.getByName(this.authorName).subscribe(author => {
    // Author exists
    if (author.id) {
      this.book.author = author;
      this.bookService.add(this.book).subscribe(() => {
        // Book added
      });
    } else {
      const authorObj: AuthorInterface = {
        fullName = this.authorName;
      }
      this.authorService.add(authorObj); subscribe(author => {
        this.book.author = author;
        this.bookService.add(this.book).subscribe(() => {
          // Book added
        });
      })
    }
  });
}

但这真的很糟糕,我相信我可以用 rxjs 使它更干净,但找不到解决方案。我对如何使用所有这些功能有点困惑。

非常感谢您的帮助。非常感谢:)

您可以使用 switchMap。此运算符订阅您传递给它的另一个可观察对象并输出其结果。

this.authorService.getByName(this.authorName)
.pipe(
  switchMap(author => {
    if (author.id) {
      this.book.author = author;
      return this.bookService.add(this.book).pipe(...);
    }
    return this.authorService.add(authorObj).pipe(
      switchMap(author => ...)
    );
  })
)
.subscribe();

如果它是一个大的可观察值(许多发出的值),你最好留在 if else

this.authorService
  .getByName(this.authorName)
  .pipe(
    mergeMap((author: any) => {
      if (author.id) {
        this.book.author = author;
        return this.bookService.add(this.book).pipe(
          tap(() => {
            console.log("book added");
          })
        );
      } else {
        const authorObj: AuthorInterface = {
          fullName: this.authorName
        };
        return this.authorService.add(authorObj).pipe(
          mergeMap((author: any) => {
            this.book.author = author;
            return this.bookService.add(this.book).pipe(
              tap(() => {
                console.log("book added");
              })
            );
          })
        );
      }
    })
  )
  .subscribe(() => console.log("job done"));

或者您可以这样做:

  const firstObservable = this.authorService.getByName(this.authorName).pipe(
      filter((author: any) => author.id != null),
      mergeMap(author => {
        this.book.author = author;
        return this.bookService.add(this.book).pipe(
          tap(() => {
            console.log("book added");
          })
        );
      })
    );

    const secondObservable = this.authorService.getByName(this.authorName).pipe(
      filter((author: any) => author.id == null),
      mergeMap((author: any) => {
        const authorObj: AuthorInterface = {
          fullName: this.authorName
        };
        return this.authorService.add(authorObj).pipe(
          mergeMap((author: any) => {
            this.book.author = author;
            return this.bookService.add(this.book).pipe(
              tap(() => {
                console.log("book added");
              })
            );
          })
        );
      })
    );

    merge(firstObservable, secondObservable).subscribe(author =>
      console.log("job done")
    );