2014-01-14 20 views
5

工場でサーバーに複数のajaxリクエストを避けようとしています。私はすでに小さなキャッシングサービスを追加しましたが、私が目指すものは十分ではありません。このファクトリは、サーバが応答する前に何度か呼び出され、サーバへの複数のリクエストの生成を引き起こします。複数のajaxリクエストを避けるangularJS

これを避けるために、AJAXリクエストが実行され、オブジェクトがまだキャッシュに入っていない場合、2番目の約束が解決されるのを待つよりも、何かが見当たりません。あなたはgetUserメソッドを実行

myApp.factory('User', ['Restangular', '$q', 
    function (Restangular, $q) { 
    var userCache, alreadyRun = false; 
    return { 
     getUser: function() { 
     var deferred = $q.defer(), firstRun= $q.defer(); 

     if (!userCache && !alreadyRun) { 
      alreadyRun = true; 

      Restangular.all('user').getList().then(function (user) { 
      console.log('getting user live '); 
      userCache = user[0].email; 
      firstRun.resolve(user[0].email); 
      }); 
     } else if (!userCache && alreadyRun) { 
      console.log('waiting for the first promise to be resolved '); 
      firstRun.then(function(user) { 
      console.log('resolving the promise'); 
      deferred.resolve(userCache); 
      }); 

     } else { 
      console.log('resolving the promise from the cache'); 
      deferred.resolve(userCache) 
     } 
     return deferred.promise; 
     } 
    }; 
    } 
]); 
+0

最終的な実装を回答に追加しました。 –

答えて

6

リクエストが既に行われている場合は、元の約束を返すことができます。このようなものはうまくいくはずです。

myApp.factory('User', ['Restangular', '$q', 
    function (Restangular, $q) { 
    var deferred = false; 

    return { 
     getUser: function() { 

     if(deferred) { 
      return deferred.promise; 
     } 

     deferred = $q.defer(); 

     Restangular.all('user').getList().then(function (user) { 
      deferred.resolve(user[0].email); 
     }); 

     return deferred.promise; 
     } 
    }; 
    } 
]); 

はまたRestangular documentation for caching requests

+0

@smilledgeをお寄せいただきありがとうございます。その間、私は質問をしたときから何かを自分で実装しました。しかし、あなたのソリューションは本当にクリーンでコンパクトに見えるので、私はあなたの答えを受け入れました。私のことを見て、あなたがそれについて何を考えているか教えてください:) –

0

毎回、新しい延期がfirstRunのために作成されます。

は、これは私のコードです。すでに実行されている場合はfirstRun.thenを呼び出しますが、その約束は決して解決されません。

+0

しかし、何をしようとしているのかを達成する方法はありますか? –

+0

文脈がなくてもあなたに伝えることはできません。 GetUserはすぐにたくさんの場所から呼び出されていますか?ルート上でResolveを使用すると、作業を開始する前にロードされていることを確認できます。 –

+0

こんにちは@JonathanRowny私は自分の実装で答えを加え、見て、あなたの考えを知らせてください。それは本当にきれいに見えるので私はsmillgeで答えを受け入れた。 –

0

を見ているすべての答えのおかげでは、その間に私は、その特定の工場をキャッシュする方法を見つけた:

.factory('User', ['Restangular', '$q', 
    function (Restangular, $q) { 
    var userCache, promises = []; 
    return { 

     getUser: function() { 

     var deferred = $q.defer(); 

     if (promises.length > 0) { 

      promises.push(deferred); 

     } else if (!userCache) { 

      promises.push(deferred); 

      Restangular.all('user').getList().then(function (user) { 
      var i; 
      userCache = user[0]; 
      for (i = promises.length; i--;) { 
       promises.shift().resolve(userCache); 
      } 
      }); 

     } else { 

      deferred.resolve(userCache); 

     } 

     return deferred.promise; 

     } 
    }; 
    } 
]); 

基本的な考え方は、作成することです。 userCacheが準備されていない間に約束の配列を取得し、要求が準備できたらキュー全体を解決し、最後に将来の要求ごとにキャッシュされた値で直接約束を解決します。

私はこのpromise caching hereの実装について説明しました。

関連する問題