如何缓存和共享 Http get() 响应?

How to cache and share Http get() response?

学习这门课程 https://www.pluralsight.com/courses/angular-2-getting-started and github materials product.service 在该课程中尝试 避免每次单击 link 时调用 http.get() 请求。 我认为每次加载文件而不是将其作为对象保存在内存中是一种很大的浪费。

正在尝试替换此代码:

    getProducts(): Observable<IProduct[]> {
    return this._http.get(this._productUrl)
        .map((response: Response) => <IProduct[]> response.json())
        .do(data => console.log('All: ' +  JSON.stringify(data)))
        .catch(this.handleError);
}

这个:

    public _observable: Observable<IProduct[]>;

    getProducts(): Observable<IProduct[]> {
    console.log('_observable before: ' + (this._observable));
    if(this._observable===undefined){
        console.log('_observable inside 1: ' + (this._observable));
        this._observable=this._http.get(this._productUrl)
            .map((response: Response) => <IProduct[]> response.json())
            .do(data => console.log('All inside observable: ' +  JSON.stringify(data)))
            .catch(this.handleError);
        console.log('_observable inside 2: ' + (this._observable));
    }

    console.log('_observable after: ' + (this._observable));
    return this._observable;
}

如果 this._observable 未定义 this._observable=this._http.get(this._productUrl)

,则不应调用此行

但是它被调用了!!!!

在 chrome 控制台中:

_observable before: [object Object]
product.service.ts:25 _observable after: [object Object]
product.service.ts:20 All inside observable:...

最后一行不应该出现!

_observable before是log中的对象。 "last line" 注释在 if-else 之外。为什么不试试 :

    if (!Object.keys(this._observable).length) {
   console.log('_observable inside 1: ' + (this._observable));
    this._observable=this._http.get(this._productUrl)
        .map((response: Response) => <IProduct[]> response.json())
        .do(data => console.log('All inside observable: ' +  JSON.stringify(data)))
        .catch(this.handleError);
        console.log('_observable inside 2: ' + (this._observable));
        return this._observable;
   } else {
        console.log('_observable after: ' + (this._observable));
        return this._observable;
   }

为您的代码

 getProducts(): Observable<IProduct[]> {
return this._http.get(this._productUrl)
    .map((response: Response) => <IProduct[]> response.json())
    .publishReplay(1)
     .refCount()
    .do(data => console.log('All: ' +  JSON.stringify(data)))
    .catch(this.handleError);
}

现在你不需要考虑那些条件了。 publishReplay、refCount 将在所有观察者之间共享相同的状态。所以 publishReplay 将帮助您缓存数据,refCount 将帮助观察者可用。

为避免加载文件,您需要在 if 语句中包含以下代码行:

            .publishReplay(1)
            .refCount()

完整代码在这里:

    getProducts(): Observable<IProduct[]> {
    console.log('_observable before: ' + (this._observable));
    if(this._observable===undefined){
        console.log('_observable inside 1: ' + (this._observable));
        this._observable=this._http.get(this._productUrl)
            .map((response: Response) => <IProduct[]> response.json())
            .publishReplay(1)
            .refCount()
            .do(data => console.log('All inside observable: ' +  JSON.stringify(data)))
            .catch(this.handleError);
        console.log('_observable inside 2: ' + (this._observable));
    }

    console.log('_observable after: ' + (this._observable));
    return this._observable;
}