在 Angular 中使用 shareReplay(1) - 仍然调用 http 请求?
Posted
技术标签:
【中文标题】在 Angular 中使用 shareReplay(1) - 仍然调用 http 请求?【英文标题】:Using shareReplay(1) in Angular - still invokes http request? 【发布时间】:2018-12-05 06:11:32 【问题描述】:我创建了一个演示 (ng-run),其中有一个调用 Http 请求的按钮。
当按钮被点击时,我调用这个方法:
public getData()
this._jokeService.getData().subscribe();
这反过来调用它(从服务):
public getData()
return this.http.get(API_ENDPOINT).pipe(shareReplay(1))
问题是每次点击时 - 我仍然看到发起了一个新的 http 请求:
问题:
为什么 shareReplay 不保留响应的最后一个值? 如何让我的代码只调用一次 http 并保留该值以供将来订阅?
编辑:solution is here
【问题讨论】:
为什么不会你看到一个新的请求?你又打电话给http.get
了! shareReplay
可防止返回的 observable 的其他订阅者触发新响应,但您每次都在创建一个新响应。如果您想发出单个请求,则将现有值公开给未来的订阅者使用ReplaySubject
,正如我在这里展示的那样:***.com/a/41554338/3001761。然后,您可以区分触发新请求和请求现有值,加上如果您确实需要发出额外请求,所有现有订阅者都会在可用时收到新结果。
我认为我不需要创建一个中间 ReplaySubject
来保持这些值。恕我直言 - 没有它也可以完成。
是的,没有它也可以完成,只要你只想要一个值。但是您仍然需要存储和公开一个可观察对象,不要每次都创建一个新对象。
是的,这是我的愚蠢错误。我每次都创建一个新的可观察对象(发生)
我写了一个库 ngx-RxCache github.com/adriandavidbrand/ngx-rxcache 来帮助你在 Angular 中管理这样的事情。在这里阅读它medium.com/@adrianbrand/…
【参考方案1】:
如果每次调用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)
【讨论】:
是的,我每次都创建了一个新的 observable ......那是我的错误。 Tnx。)。这是漫长的一天...... @siva636 我明白你在这里做什么,但你能告诉我你的方法比简单地在你的服务中管道 http.get 并提取数据并将其放入一个不可观察的变量中的好处服务?【参考方案2】:在役:
getData$ = this.http.get(API_ENDPOINT).pipe(shareReplay(1));
在组件中,需要取消订阅,一次API调用可以多次订阅:
ngOninit()
this.data$ = this._jokeService.getData$;
this.data$.subscribe()
在模板中,使用:
*ngIf="data$ | async as data"
【讨论】:
以上是关于在 Angular 中使用 shareReplay(1) - 仍然调用 http 请求?的主要内容,如果未能解决你的问题,请参考以下文章
RxSwift:如何使用 shareReplay 懒惰地获取订阅
node_modules/rxjs-compat/operator/shareReplay.d.ts(2,10) 中的错误:
[RxJS] Reactive Programming - Sharing network requests with shareReplay()