2011-09-13 5 views
0

私はデータを扱うクラスを持っています。他のクラスはその値を与えることができ、データクラスはそれを設定します。コールバック付きのキャッシュパターン

それは次のようになります。私は直面しています問題は、私が追加したすべての方法は、製品が存在するかどうかを確認しなければならないことである

class Data 

    constructor : -> 
    @products = null 

    populateProducts : (callback)=> 
    ajaxCall (data)=> 
     @products = data 
     callback() 

    allProducts : (list)=> 
    if @products? 
     list = @products 
    else 
     @populateProducts => allProducts list 

。だから私はコードのその部分を再利用可能にする方法を検討しています。私が試した

一つの方法は、以下の通りであった:

productsCheck : (callback)=> 
    if @products? 
     callback() 
    else 
     @populateProducts => products callback 

この方法を使用すると、私はallProducts簡素化することができます:最後に

allProducts : (list)=> 
    @productsCheck => list = @products 

を私はありません技術を探しています:「製品はドンが」データベースからそれらを移入します。私はこれが既知のパターンかもしれないと考えていた可能性があります。

答えて

1

@productsを非同期に読み込み、オブジェクトのすべてのメソッドが@productsをロードする(潜在的に)待機する必要があるため、オブジェクトのすべてのメソッドが非同期であり、その結果をコールバックに返す必要があります。これを回避する方法はありません。非同期JSコードを同期させることはできません。 allProductsは単に値を返すことはできません。ここで

は、あなたが何をすべきかです:まず、populateProductsを変更するので、それはそれが持っていない場合、Ajax呼び出しをすることはありません。

populateProducts : (callback) => 
    if @products? 
    callback() 
    else ajaxCall (data) => 
    @products = data 
    callback() 

をそれからちょうどを呼び出して@productsを使用する各メソッドを開始します@populateProductsのように:

allProducts : (callback) => 
    @populateProducts => 
    callback @products 

firstProduct: (callback) => 
    @populateProducts => 
    callback @products[0] 

# ... 
4

下線は、ID(すなわち、最初の引数)への関数呼び出しの結果をキャッシュする_.memoize

の概念を有します。

Memoizationは実装が簡単なパターンです。

var memoize = function _memoize(f) { 
    var cache = {}; 
    return function _intercept(arg) { 
    if (cache[arg]) return cache[arg]; 
    return (cache[arg] = f.apply(this, arguments)); 
    } 
}; 

このパターンは、コールバックと非同期で動作するように調整する必要があります。ここでは、完全なネスについては

_.memoizeコードは次のとおりです。

_.memoize = function(func, hasher) { 
    var memo = {}; 
    hasher || (hasher = _.identity); 
    return function() { 
    var key = hasher.apply(this, arguments); 
    return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); 
    }; 
}; 

下線は引数に基づいて一意のキーを生成します2番目の引数としてhasherを受け入れているようです。 (デフォルトはID関数のアンダースコアです)。

hasOwnPropertyと思われるので、toStringvalueOfのような面倒なキーを使用すると、プロパティチェックで真実を示すようになります。

+0

ああ、それを調べるのは素晴らしいことです。その名前を公に宣言する必要がないことを願っています。 – Pickels

関連する問題