Angular API调用:Observable vs Promise

3
我有一个服务,调用API获取一堆电影描述并返回 Observable:
getNowPlayingMovies$(page: number, country?: string): Observable<NowPlaying> {
    console.log(`${this.baseUrl}${this.now_playing}?${this.key}&region=${country || 'US'}&page=${page}`);
    return this.http.get<NowPlaying>(
      `${this.baseUrl}${this.now_playing}?${this.key}&region=${country || 'US'}&page=${page}`
    );
  }

在使用上述函数的组件中,我会在每次页面值改变时调用它,以便在组件视图中为用户提供分页功能。
这是调用服务的组件:
getNowPlayingMovies(): void {
    this.nowPlayingService.getNowPlayingMovies$(this.page).subscribe((data) => {
      this.nowPlaying.push(
        ...data.results.filter((result) => result.backdrop_path)
      );
      if(!this.last_page){
        this.last_page = data.total_pages
        this.page++;
      } else if(this.page <= data.total_pages) {
        this.page++;
      }
      console.log(data);
      console.log(this.nowPlaying);
    });
  }

我已经阅读过,在Angular中,你应该总是尝试使用Observable而不是Promises编写代码,但在像这样的场景中,我看不到订阅api调用响应的任何优势。
将服务中的Observable转换为Promise是否正确呢?
getNowPlayingMovies$(page: number, country?: string): Promise<NowPlaying> {
    console.log(`${this.baseUrl}${this.now_playing}?${this.key}&region=${country || 'US'}&page=${page}`);
    return this.http.get<NowPlaying>(
      `${this.baseUrl}${this.now_playing}?${this.key}&region=${country || 'US'}&page=${page}`
    ).toPromise();
  }

我正在学习Angular,并将其添加到我的作品集中,因此我想学习以正确和最佳的方式实现它。


1
请查看此链接,了解在Angular中使用可观察对象和HTTP的好处:https://dev59.com/8Lzpa4cB1Zd3GeqPRslP - Moshezauros
是的,两种方式都可以工作,但我希望有更多经验的人能够解释一下它们之间的区别以及哪种选项更合适。 - jcobo1
1个回答

4

在这种情况下,使用“它将起作用”是不会有错误的。

将代码转换为Promise会丢失一些功能,但最重要的一个通常是无关紧要的:根据我的经验,http上的方法不会返回发出多个值的可观察对象。请注意,可观察API确实留下了这种可能性。您可以深入了解相关源代码以获取更多信息。

许多资源可能仍然建议您使用可观察对象,其中一个原因是Angular中的许多其他功能都可以/应该使用可观察对象构建。考虑使用响应式表单、组合多个http请求、用户事件等。如果您坚持使用可观察对象来处理它们,RxJs提供了强大(尽管可能过于复杂和/或复杂)的组合方式。例如:

  • 一个http.get可观察对象来检索电影
  • 用户在输入字段中输入,可能通过debounce进行pipe
  • 将其与http.post相结合以查询备选电影
  • combineLatest所有这些,并可能通过debouncedistinctUntilChanged进行pipe以在正确时间进行UI更新
  • 等等。

当您立即将http调用转换为Promise<T>时构建所有这些交互将是一项额外的工作,并且可能感觉不符合惯用法。

话虽如此,我有时会做出您所描述的事情,并“简化”服务,使其返回承诺而不是可观察对象。但在大多数情况下,这可能乍一看是个好主意,但以后会让事情变得更加困难。


谢谢Jeroen,这就是我一直在寻找的那种解释。所以,根据我发布的示例,也许最好的选项是从我的服务中返回一个observable,但是在组件上使用管道运算符将其转换为promise?因为当我订阅时唯一要做的事情就是将响应值存储在变量中。 - jcobo1
嗯。虽然我不确定为什么你的组件要把它转换成 Promise?组件只需订阅结果并使用它,或者您可以使用 async 管道(它会为你处理订阅/取消订阅),直接在组件中查看电影即可。 - Jeroen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接