Angular/RXJS 嵌套的 observables 在后两次调用中使用第一次调用的响应

Angular/RXJS nested observables using the response from the first call in the second two calls

我有一个 POST 请求创建一个 returns 一个 Observable 的电影,这个请求的结果 returns 我需要一个 ID,我需要使用这个 ID 发出两个进一步的请求用于添加导演和电影图像的 ID。

我有以下调用,在添加 Director 时效果很好,但是当我到达第二个 flatMap 时,我无法在不添加订阅的情况下将图像循环到 POST 它们结束。

有更好的方法吗?我已经尝试过 switchMap、mergeMap 和 map,但如果没有订阅,我无法触发第二个请求。

this.Movie.createMovie(movie).pipe(
      map((movie: Movie) => {
        return movie;
      }),
      switchMap((movie: Movie) => this.movieRepository.postDirector(director, movie.id)),
      flatMap((director: Director) => {
        return movieImages.map((image) => {
          return this.movieRepository.addMovieImage(image, director.movie_id).subscribe()
        });
      })
    ).subscribe({
      next: (response: any) => {
        console.log(response)
      }
    })

将您的数组转换为可观察数组并 运行 它们在 forkJoin

flatMap((director: Director) => {
    return forkJoin(movieImages.map((image) => {
      return this.movieRepository.addMovieImage(image, director.movie_id)
    }));
})

假设你想保存导演和图像,并且两个调用都必须在我保存另一部电影之前完成,我会这样处理它

 this.Movie.createMovie(movie).pipe(
    concatMap((movie: Movie) => {
      const saveDirectory$ = this.movieRepository.postDirector(director, movie.id);
      const saveMovieImage$ = this.movieRepository.addMovieImage(image, director.movie_id);

     return forkJoin(saveDirectory$, saveMovieImage$).pipe(map(([directoryAPIresponse, imageApiResponse])=>{
       // you can check if the both records created based on your api response;
       return of(true);
     }));
    )).subscribe({
      next: (response: any) => {
        console.log(response)
      }
    })

我使用 concatMap 的原因是我想等待内部 api 完成后再进行另一个调用。

forkJoin:我希望两个内部 API 都完成。

好问题;

也许您需要的是正确编排操作,为此您可以使用元组(对)和更有序的代码,如下所示:

this.Movie.createMovie(movie)
  .pipe(
    concatMap(movie => this.movieRepository.postDirector(director, movie.id).pipe(map(director => [movie, director]))),
    concatMap(pair => this.movieRepository.addMovieImage((pair[0] as Movie).image, (pair[1] as Director).movie_id))
  )
  .subscribe(response => console.log(response));

您也可以使用 switchMap 而不是 concatMap。 如果您需要有关如何编排操作的更多信息,我推荐以下文章:Clean the operators's chain in RxJS.

您好,希望对您有所帮助。