在Angular中使用shareReplay(1) - 仍会调用http请求吗?

63

我创建了一个演示(ng-run),其中有一个按钮,可以调用Http请求。

当按钮被点击时,我会调用这个方法:

public getData(){
 this._jokeService.getData().subscribe();
}

接着从服务中调用这个函数:

 public getData() {
    return this.http.get(API_ENDPOINT).pipe(shareReplay(1))
  }

问题在于每次点击时,我仍会看到一个新的HTTP请求被启动:

enter image description here

问题:

为什么shareReplay不会保留响应的最后一个值?
我该如何让我的代码只调用一次http并将该值保存供未来的订阅使用?

编辑: 解决方案在这里


8
为什么你没有看到新请求?因为你再次调用了http.getshareReplay 防止返回的可观察对象的附加订阅者触发新的响应,但是每次都会创建一个新的可观察对象。如果您想只进行一次请求并将现有值暴露给将来的订阅者,请使用我在此处显示的 ReplaySubject :https://dev59.com/cFgR5IYBdhLWcg3wO7U0#41554338。然后,您可以区分触发新请求和请求现有值,而且如果确实需要进行额外的请求,则所有现有的订阅者在可用时都会收到新的结果。 - jonrsharpe
我认为我不需要创建一个中间的ReplaySubject来保存这些值。我个人认为 - 它可以在没有它的情况下完成。 - Royi Namir
是的,如果你只需要一个值,那么可以不用它来完成。但是你仍然需要存储和公开一个单一的可观察对象,而不是每次都创建一个新的。 - jonrsharpe
是的,这是我的一个愚蠢错误。我每次都创建了一个新的可观察对象(happens)。 - Royi Namir
我编写了一个库ngx-RxCache https://github.com/adriandavidbrand/ngx-rxcache,以帮助您在Angular中管理此类事物。请在这里阅读有关它的信息https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb - Adrian Brand
2个回答

68

如果每次调用this.http.get(API_ENDPOINT).pipe(shareReplay(1)),都会触发一次HTTP请求。如果想要只进行一次HTTP请求并缓存数据,建议使用以下方法。

首先获取数据的 observable:

 ngOninit(){
    this.data$ =  this._jokeService.getData().pipe(shareReplay(1));
    }

现在可以多次订阅:

 public getData(){
     this.data$.subscribe();
    }

您的服务:

public getData() {
    return this.http.get(API_ENDPOINT)
  }

7
是的,每次我都创建了一个新的可观察对象...这是我的错误。谢谢你。今天真是漫长的一天... - Royi Namir
6
我理解您在这里做什么,但是您能告诉我您的方法相比于在服务中直接使用http.get将数据提取并放入非可观察变量的方法的优势吗? - lolplayer101
这可以简化为 shareReplay({bufferSize:1, refCount: false}) - Patrick

10

在服务中:

getData$ = this.http.get(API_ENDPOINT).pipe(shareReplay(1));

在组件中,需要取消订阅,您可以通过单个API调用多次订阅。
ngOninit(){
   this.data$ =  this._jokeService.getData$;
   this.data$.subscribe() 
}

在模板中,使用以下代码:
*ngIf="data$ | async as data"

无需取消http请求,有限可观察对象是在应用程序结束之前某个时刻停止发出值的对象,而无限可观察对象将一直持续到时间的尽头(当您关闭浏览器选项卡时)。请参阅此链接https://www.seangwright.me/blog/development/unsubscribe-angular-2-http-observables/。 - moh
@moh 是的,你是对的。请不要传播虚假/过时的信息。 https://github.com/angular/angular/issues/46542 - undefined

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