RxJs:使用async / await共享一个Observable

时间:2017-08-24 01:20:38

标签: javascript angular rxjs

使用RxJs 5和Angular 4。

我想共享一个observable,以便我只发出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设置为共享的observable,当我调用.toPromise()时,它将获取缓存的值并使其成为一个承诺,我可以await

它应该如何运作?

2 个答案:

答案 0 :(得分: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",这样用户就不会多次点击按钮。

答案 1 :(得分:1)

由于share的工作方式,observable重新订阅toPromise,会产生新的请求。

Promises已经提供了缓存行为。考虑到promises已经在服务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;
}