从缓存或HTTP返回数据 - 有更简单的方法吗?

时间:2016-05-11 19:59:40

标签: angular

(在Angular 2应用程序中):如果数据已经在内存中,只需返回它,否则执行HTTP GET。听起来应该很简单。有没有比以下更简单的方法?

[LOGIC]

  1. 如果数据不在内存中,我们还没有启动GET, 启动GET,返回一个observable并存储 观察到。
  2. 如果数据不在内存中,但我们启动了GET,则返回 存储的observable。
  3. 如果数据在内存中,则返回一个新的observable 立即返回数据。
  4. [更新1]显然这个逻辑不起作用。我看到每次调用getTopics时都会发送GET请求! - 即使http.get方法只执行一次。每次新调用者获得原始observable的副本时,都会发送另一个GET请求!

    [更新2]我刚刚了解到“在你打电话订阅之前,观察中没有任何事情发生”。这解释了为什么在返回observable时调用GET请求。然后呼叫者立即呼叫订阅。这意味着我的逻辑肯定是错误的,我可能会回到原点解决这个“看起来很简单”的问题。

    [更新3]Günter的解决方案包括返回“共享”可观察量的非常重要的步骤。这解决了发送多个GET请求的问题。以下代码不包含此内容。

    [CODE](数据是“主题”数组)

    @Injectable()
    export class TopicsService {
    
    private _topicsUrl = 'app/topics/topics.json';
    private _topics: string[] = null;
    private _topics$: Observable<string[]> = null;
    
    
    constructor (private http: Http) {}
    
    getTopics(): Observable<string[]> {
        // if topics are in memory, return them.
        if (this._topics != null) {
            return this.getTopicsTFromMem();
    
        // otherwise get them from the file.
        } else {
            return this.getTopicsFromFile();
        }
    }
    
    // return topics from memory. Actually return an observable which will return them.
    getTopicsTFromMem(): Observable<string[]> {
        let topics$ = new Observable(observer => {
            observer.next(this._topics);
        });
        return topics$;
    }
    
    // return topics from file. Actually return an observable which will return them.
    getTopicsFromFile(): Observable<string[]> {
    
        // If someone already started the http GET, then return existing observable.
        if (this._topics$ != null) {
            return this._topics$;
        }
    
        // otherwise start the GET
        let topics$ = this.http.get(this._topicsUrl)
            .map(this.extractData)
            .catch(this.handleError);
        topics$.subscribe(topics => {this._topics = topics;});
        this._topics$ = topics$;       
        return topics$;              
    }
    
    .....
    

1 个答案:

答案 0 :(得分:0)

我认为你所概述的逻辑是正确的。 喜欢与否(我不一定喜欢它)这是一个异步世界。因此,无论是使用1 2 3步还是尝试同步检查某种本地缓存,然后,如果数据不存在,我们就会重新进入异步世界。 我希望这可以提供帮助,顺便说一下,如果有人知道不同的方式,我会很高兴听到