首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >缓存回退HTTP请求

缓存回退HTTP请求
EN

Stack Overflow用户
提问于 2017-11-01 00:22:12
回答 3查看 779关注 0票数 1

我很难弄清楚我开始构建的服务的序列。我想做的是从一个基于承诺的存储提供者加载缓存,然后用该缓存启动一个可观察到的缓存。当HTTP请求解析后,我想用新的响应替换旧的缓存。

我很难搞清楚这个过程,希望能得到任何帮助。

PSEUDOCODE

代码语言:javascript
复制
import {Injectable} from "@angular/core";
import {Http} from "@angular/http";
import rxjs/add/operators/map;
import rxjs/add/operators/startWith;
import {Storage} from "@ionic/storage";

@Injectable()
export class DataService {
    private _cache = {};

    constructor(public http: Http; public storage: Storage){}

    public getCache(): Promise<any> {
        return this.storage.get('storageKey');
    }

    public setCache(val: any): Promise<any> {
        return this.storage.set('storageKey', val);
    }

    public getData(): Observable<any> {
        // Step 1: Get cache.
        this.getCache().then(cache => this._cache = cache);

        // Step 2: Make HTTP request.
        return this.http.get('endpoint')
        // Step 3: Set data mapping
           .map(res => this.normalize(res))
        // Step 4: Use resolved cache as startWith value
           .startWith(this._cache)
        // Step 5: Set cache to response body.
           .do(result => this.setCache(result).then(() => console.log('I resolved'));    
    }

    private normalize(data: Response): any {
       // Fun data-mapping stuff here
    }
}

这段代码的目的是在移动设备上运行,在移动设备上,速度的错觉,加上离线能力是第一优先级。通过最初使用旧缓存设置视图,用户可以查看已存储的内容,如果HTTP请求失败(慢速网络,或者没有网络),没有什么大不了的,我们回到缓存。但是,如果用户联机,我们应该利用这个机会用来自HTTP请求的新响应替换旧缓存。

谢谢您的帮助,如果我需要进一步的说明,请告诉我。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-11-01 00:41:18

如果我正确理解了要求,

编辑调整后的讨论

代码语言:javascript
复制
getData() {

  // storage is the cache
  const cached$ = Observable.fromPromise(this.storage.get('data'))  

  // return an observable with first emit of cached value
  // and second emit of fetched value.
  // Use concat operator instead of merge operator to ensure cached value is emitted first,
  // although expect storage to be faster than http 
  return cached$.concat(
    this.http.get('endpoint')
      .map(res => res.json())
      .do(result => this.storage.set('data', result))
  );
}

编辑#2 -处理初始空缓存

在CodePen 这里中进行测试之后,我意识到有一个边缘情况,这意味着我们应该使用merge()而不是concat()。如果最初存储为空,concat将阻塞,因为cached$从不发射。

另外,需要添加distinctUntilChanged(),因为如果最初存储为空,merge将返回第一个fetch两次。

您可以通过注释掉在'prev value'中设置CodePen的行来检查边缘大小写。

代码语言:javascript
复制
/* Solution */
const getData = () => {
  const cached$ = Observable.fromPromise(storage.get('data'))  

  return cached$ 
    .merge(
      http.get('endpoint')
        .map(res => res.json())
        .do(result => storage.set('data', result))
    )
    .distinctUntilChanged()
}
/* Test solution */
storage.set('data', 'prev value')  // initial cache value
setTimeout( () => { getData().subscribe(value => console.log('call1', value)) }, 200)
setTimeout( () => { getData().subscribe(value => console.log('call2', value)) }, 300)
setTimeout( () => { getData().subscribe(value => console.log('call3', value)) }, 400)
票数 2
EN

Stack Overflow用户

发布于 2017-11-01 04:25:26

用优惠来确保订单?

代码语言:javascript
复制
const cache = Rx.Observable.of('cache value');
const http = function(){

  return Rx.Observable.of('http value');
                        };
var storage={}
storage.set=function(value){
 return Rx.Observable.of('set value: '+value);
}
const example = cache.concat(http().flatMap(storage.set));
const subscribe = example.subscribe(val => console.log('sub:',val));`

jsbin:http://jsbin.com/hajobezuna/edit?js,console

票数 0
EN

Stack Overflow用户

发布于 2017-11-04 11:27:31

理查德马特森,这是我得出的最后结果。我添加了一个catch子句,这可能有点多余,但是在web上使用Ionic,您将得到他们的调试屏幕,这就是为什么它在那里。catch能否得到改进,使do不能运行或其他什么?

代码语言:javascript
复制
public getFeed(source: SocialSource): Observable<any> {
    const cached$ = Observable.fromPromise(this._storage.get(`${StorageKeys.Cache.SocialFeeds}.${source}`));
    const fetch$ = this._http.get(`${Configuration.ENDPOINT_SOCIAL}${source}`)
        .map(res => this.normalizeFacebook(res))
        .catch(e => cached$)
        .do(result => this._storage.set(`${StorageKeys.Cache.SocialFeeds}.${source}`, result));
    return cached$.concat(fetch$);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47046439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档