【问题标题】:How to cache and share Http get() response? [duplicate]如何缓存和共享 Http get() 响应? [复制]
【发布时间】:2016-10-11 18:59:13
【问题描述】:

按照这门课程https://www.pluralsight.com/courses/angular-2-getting-started 和github 材料product.service 在该课程中尝试 避免每次单击链接时调用 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:...

最后一行不应该出现!

【问题讨论】:

  • ProductListComponent 是否再次订阅了 observable?如果是,它将再次执行。
  • 查看此处提供的解决方案:stackoverflow.com/questions/36271899/…
  • 实际上,您将我引导到正确的方向,即缓存和添加魔术词 publishReplay(1) 和 refCount syntaxsuccess.com/viewarticle/… 如果您发布答案,我会将其标记为答案
  • @DeborahK 谢谢你的精彩课程!

标签: angular rxjs5 angular2-http


【解决方案1】:

_observable before 是日志中的一个对象。 “最后一行”注释在 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;
   }

【讨论】:

  • 结果是一样的
【解决方案2】:

为你的代码

 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 会帮助观察者可用。

【讨论】:

  • 我希望@DeborahK 会发布这个已经完成的答案,但你是第一个
  • 没有 if 语句没有影响
【解决方案3】:

为避免文件被加载,您需要在 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;
}

【讨论】:

    猜你喜欢
    • 2012-12-16
    • 1970-01-01
    • 2011-04-21
    • 2011-03-25
    • 2012-06-27
    • 2012-08-01
    • 2015-03-10
    • 2021-02-25
    • 1970-01-01
    相关资源
    最近更新 更多