2016-09-08 21 views
0

を約束し、私はこのように見える小さなAPIインタラクションコードを持っています。私はこのAPIエンドポイントを呼び出す必要があるかもしれないいくつかの個別のディレクティブとコンポーネントを持っていますが、毎回新鮮な結果を必要としません。しかし、これは醜い競合状態に陥ります。load_posts応答が到着する前に2つ以上のコンポーネントがget_postsメソッドを呼び出すと、それらはすべてAPIリクエストを発行します。これは単なるキャッシュの試行であるため、副作用はありませんが、目的をすべて破ります。競合状態がそう

これを進める方法についてのアイデアはありますか?

答えて

0

$ HTTPサービスは要求をキャッシュすることができます。キャッシングの仕組みの詳細については、See hereまたはdocsを参照してください。

デフォルトのhttpキャッシュは、Googleのデータ が頻繁に変更されない場合に特に便利です。私たちは、そのようにそれを設定することができます。

$http({ 
    method: 'GET', 
    url: '/api/users.json', 
    cache: true 
}); 
// Or, using the .get helper 
$http.get('/api/users.json', { 
    cache: true 
}); 

は今、URL /api/users.jsonに$ HTTPを介して行われるすべての要求は、デフォルトの$ HTTPキャッシュに保存されます。 のキーは、$ httpキャッシュ内のこの要求はフルパスのURLです。

0

これは実際に競合状態の問題ではなく、単にその機能をメモすることの問題です。あなたはUnderscore.jsからmemoize()ようなものを使用するか、単にそれを自分で実装することができます。

var load_posts =() => { 
    const p = $http 
    .get('/posts') 
    .then(response => response.data); 
    load_posts =() => p; 
    return p; 
}; 
-2

1)データを個別の「blogService」サービスに抽出します。

2)あなたのサービスでリクエストを行うと約束します。

3)すべてのクライアントに対して同じ約束を返し、応答オブジェクト全体を公開したくない場合は結果を操作できます。

var promise = null; 

function loadBlogs() { 
    promise = promise || $http.get("/posts").then(function(response){return reponse.data;}); 
    return promise; 
} 

4)それからちょうどサービスメソッドを呼び出すと、あなたは(コントローラ、ディレクティブなど)を必要な場所解決するための約束を待ち:

function getPosts() { 
    blogService.loadBlogs().then(function (posts) { 
     vm.posts = posts; 
    }); 
+0

私は内部応答データのすべてを公開する必要はありませんクライアントに。だからこそ、投稿記事は記事の読み込みとは異なる。 – vinnylinux

+0

@JaromandaXはい、そうです。コードを修正しました。 –

+0

もう少し微妙だが重要な違いがある。私の答えでは、私は、キャッシュが別のサービス(シングルトンになる)で実行されるべきであることを強調しました。コントローラーや指示には直接アクセスしません。 –