2016-03-25 16 views
1

私は、HTTPから値を取得し、localStorageにputして$ q promiseを返すget(url)メソッドを持つcacheServiceを実装しました。次の.get(url)を実行すると、localStorageから値が取得され、$ qでラップされた値が返されます。角度アプリケーションでHTTP要求を同期する方法は?

function get(url){ 
    var saved = JSON.parse(localStorage.getItem(url)); 
    if (angular.isObject(saved)){ 
     return $q.when(saved); 
    } 
    return $http.get(url).then(function(xhr){ 
     localStorage.setItem(url, JSON.stringify(xhr.data)); 
     return xhr.data; 
    }); 
} 

私の方法がうまくいかず、2つ以上のHTTPリクエストが発生する場合があります。

私は二度(例えば、異なるモジュールからの)cacheService.get(URL)を呼び出す場合:

  • それは最初の時間を実行するとき、それはのlocalStorageでキャッシュ値を検索し、HTTPリクエスト
  • を作るいません最初のHTTP要求がまだ実行されておらず、その結果値がまだキャッシュされていません。だから私の方法は、HTTP要求を2回目にします。

私はそれが好きではありません。

そこで質問です:

URLごとに1つだけの要求を持っているurlでリクエストをsyncroniseする方法?

UPD:私はアイデア持って :

  • のlocalStorageが値をキャッシュしている場合var currentRequests = {};
  • を定義し、currentRequests[url]が空の場合、1
  • を返し、要求を行うと、currentRequests[url] = $http.get(url)を設定 - currentRequsts[url]が空でない場合は、
  • に約束を格納してください。この要求は現在実行されており、その後はちょうどreturn currentRequests[url]です。

JSはブラウザでは1つのスレッドで実行されるため、currentRequestsはスレッドセーフです。しかしそれはnodejsにはありません。正しい?

あなたはどう思いますか?

+0

私はそれが役立つかどうかわからないんだけど、 '$ httpProvider.interceptors' –

+0

を見てみましょう、あなたは同じURLにすべての要求か、単に要求を同期しますか? –

+0

@AmanGautamもちろん、同じURLへの要求です。 URLごとに1つずつまた、UPDの質問を参照してください。 – omickron

答えて

1

それは良い解決策ではないかもしれません。しかし、あなたはそれを試すことができます。

私は約束の配列を維持することをお勧めします。

var promiseArr = []; 
function get(url){ 
    var saved = JSON.parse(localStorage.getItem(url)); 
    if (angular.isObject(saved)){ 
     return $q.when(saved); 
    } 
    //check if $http request for the url has a pending promise. 
    if(!promiseArr.hasOwnProperty(url)){   
     promiseArr[url] = $http.get(url).then(function(xhr){ 
      localStorage.setItem(url, JSON.stringify(xhr.data)); 
      delete promiseArr[url]; //Delete the promise once resolved.. please check. 
      return xhr.data; 
     }); 
    } 
    return promiseArr[url]; //return the promise from the array. 
} 
+0

私は同じ考えを持っています。しかし、この方法はスレッドセーフであろうか? – omickron

+0

yupの'thread-safe' .. 'service'はアプリケーションのスパンを通して一度だけインスタンス化されるからです。 – Minato

+0

はい、サービスはシングルトンで、別のスレッドから実行できます。 – omickron

関連する問題