2017-02-16 6 views
2

私はAPIからデータセットを取得するデータサービスを作成しましたが、まずそれをローカルにキャッシュし、同じデータがすでに利用可能かどうかを確認します失効したデータ要素は気にしないでください...私はそれを次に扱います)。ここに私のコードです:それは正しいキャッシュされたデータを見つけたデータを初めて取得するために、さらに2回目の呼び出しに私は(コンソールログから)見ることができます正常に動作しますデータの取得とキャッシングにAureliaの約束を使用

getData(url, use_cache = true) { 
    // Http Fetch Client to retreive data (GET) 
    let cache_index = this.cache.findIndex(r => { return r.url === url; }); 
    if ((use_cache) && (cache_index > -1) && (this.cache[cache_index].data.length)) { 
    // Use cached data (available) 
    console.log("Found cached data!", this.cache[cache_index].data); 
    // 
    // I think this next line is the problem... need to return a promise??? 
    // 
    return this.cache[cache_index].data; 
    } else { 
    console.log("Retrieving records from " + url); 
    return this.httpClient.fetch(url, { 
     credentials: 'include' 
    }).then(response => { 
     // Old statement was simple... 
     // return response.json(); 

     // New method seems to be working because it's saving the data into the cache 
     return response.json().then(result => { 
     this.cache.push({'url': url, 'data': result}); 
     // Not sure why I need this next line, but I do. 
     return result; 
     }); 
    }); 
    } 
} 

が、私は取得しています私が信じている誤りは、私の専門分野にまだない、約束に関連している。

エラーメッセージ: ERROR [app-router] TypeError: this.core.getData(...).then is not a function

このエラーは、私のviewmodelの呼び出し元に実際にある次のようになります。

getAccounts() { 
    this.core.getData('/accounting/account/all').then(response => { 
    this.accounts = response; 
    }); 
} 

私が代わりに約束を返すので、データがキャッシュされているときので、推測実際にデータを返しています。生データには.thenメソッドがありません。

私は、データがキャッシュされたときに戻るために(たとえ非同期トランザクションではないにしても)偽の約束を作成するか、データサービスからこのメソッドを呼び出す(またはデータを返す) 。

この問題を解決する方法はありますか? Aureliaに関連するこのトピック全体に関する無料のアドバイスはありますか?

答えて

4

データがキャッシュされていると、約束を返すのではなく、実際にデータを返すので、生データには.thenメソッドがありません。

はい。

私は偽のデータが

Promise.resolveを使用して)可能

をキャッシュされた場合に返す約束(それは非同期トランザクションではありませんが)、ないを作成するいずれかの必要があると思います。

...私のデータサービス(またはデータを返す)からこのメソッドを呼び出す方法を改善します。

いいえ、必ずしも必要ではありません。

代わりに、もっと簡単な解決策があります:約束オブジェクト自体をキャッシュし、そのURLのすべての呼び出しから同じ約束を返してください!

getData(url, use_cache = true) { 
    // Http Fetch Client to retreive data (GET) 
    if (use_cache && url in this.cache) 
    return this.cache[url]; 
    else 
    return this.cache[url] = this.httpClient.fetch(url, { 
     credentials: 'include' 
    }).then(response => response.json()); 
} 

これは、あなたが同じリソースのための2つの並列要求を持っていることは決してないだろう追加の利点がある - 要求自体がキャッシュされているだけでなく、到着した結果を。唯一の欠点は、エラーを回避し、それ以降の呼び出しで再試行したい場合はエラーをキャッシュし、拒否にキャッシュを落とさなければならないことです。

+0

これは驚くべき解決策だと言わざるを得ない!もし私がそれを10倍アップヴォートすることができたら、私はそうするだろう! – LStarky