2017-08-24 51 views
0

使用RxJs 5角4RxJs:共享使用异步可观察/等待

我想分享一个可观察的,这样我只能让1个Http请求,我也希望让我去等待来电当我请求它的结果。我有以下代码:

export class DataService { 
    constructor(public http: HttpClient) { 
     this.getObservable(); 
    } 

    public observable; 

    public getObservable() { 
     const url = "api/getData"; 
     this.observable = this.http.get(`${this.baseUrl}${url}`).share() 
    } 

    public async hasData(data: DataEnum) {   
     const result = await this.observable.toPromise(); 
     return result.filter(x => x === data).length > 0; 
    } 
} 

但是,许多调用hasData导致了许多调用我们的API端点。我假设我已将observable设置为共享的观测值,当我打电话给.toPromise()时,它只会获取缓存的值并将其作为承诺,我可以await

这是应该如何工作?

+0

你为什么要这么做?我们可以用更好的技术来帮助你? – Microsmsm

+0

如果您已经使用承诺,是否有某些事情阻止您保存承诺?这将是非常简单的。共享运营商无法按照您的预期工作。 – estus

+0

@Microsmsm代码被简化了:)当应用程序加载时,我需要知道在哪里指导用户 - 因此需要等待结果。该数据还包含HTML模板中请求的其他一些信息,因此我们会收到很多电话,我想分享。 – user917170

回答

1

你的代码对我来说似乎过于复杂。我可能会做这样的事情:

private data = null; 

getData():Observable<> { 
    // if data is already available, return it immediately 
    if (this.data) return Observable.of(this.data); 

    // else, fetch from the server and cache result 
    return this.http.get(url).do(data => this.data=data) 
} 

所以每当你想要的数据,你只是做:

this.getData().subscribe(
    data => console.log(data); 
) 

为了确保数据到达之前,你不会打电话给你的API端点多次,你有几个选择。

  • 调查data resolvers - 这些将不会初始化您的组件,直到数据到达。在ngOnInit数据将准备好同步,所以没有多次呼叫服务器的风险。

  • 或者,您可以隐藏视图,直到数据准备好与*ngIf="data",因此用户不会多次单击按钮。

+0

这样做的问题是'数据'是异步设置的,所以如果我快速连续调用两次'getData()'并且api调用需要一些时间,它将被调用两次。 – user917170

+0

@ user917170我添加了一点到我的答案。 – BeetleJuice

+0

好的我认为数据解析器实际上是问题的正确解决方案,在我的问题中不一定清楚,但是我们希望阻止加载路由,直到服务调用返回。谢谢! – user917170

1

由于如何share作品,observabletoPromise重新订阅,部份产生新的要求。

承诺已经提供了缓存行为。考虑到许诺已经在服务API中使用,它们可以独家使用:

constructor(public http: HttpClient) { 
    this.getPromise(); 
} 

public promise; 

public getPromise() { 
    const url = "api/getData"; 
    this.promise = this.http.get(`${this.baseUrl}${url}`).toPromise() 
} 

public async hasData(data: DataEnum) {   
    const result = await this.promise; 
    return result.filter(x => x === data).length > 0; 
} 
+0

感谢您的回答,这可能会奏效,但实际上路由守卫数据解析器是修复它的'角度'方法。 – user917170