Javascript 带回调的缓存模式
我有一个处理数据的类。其他类可以给它它们的值,数据类将填充它们 看起来是这样的:Javascript 带回调的缓存模式,javascript,design-patterns,coffeescript,Javascript,Design Patterns,Coffeescript,我有一个处理数据的类。其他类可以给它它们的值,数据类将填充它们 看起来是这样的: class Data constructor : -> @products = null populateProducts : (callback)=> ajaxCall (data)=> @products = data callback() allProducts : (list)=> if @products?
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 : (list)=>
@productsCheck => list = @products
最后,我正在寻找这样的技术:“如果产品不存在,则从数据库中填充它们”。我可能在想,这可能是一种已知的模式,因此,如果是这样的话,关于它的信息也值得赞赏。下划线有 它将缓存对id(即第一个参数)的函数调用的结果 是一种易于实现的模式
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 = 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));
};
};
下划线似乎接受一个hasher
作为第二个参数,它将根据这些参数生成一个唯一的键。(默认为下划线标识函数)
它似乎还使用了hasOwnProperty
,因此您可以使用恼人的键,如toString
和valueOf
,这些键将在属性检查中标记truthy。下划线的概念是
它将缓存对id(即第一个参数)的函数调用的结果
是一种易于实现的模式
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 = 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));
};
};
下划线似乎接受一个hasher
作为第二个参数,它将根据这些参数生成一个唯一的键。(默认为下划线标识函数)
它似乎还使用了hasOwnProperty
,因此您可以使用恼人的键,如toString
和valueOf
,这些键将在属性检查中标记truthy。因为您正在异步加载@products
,对象上的每个方法都必须(可能)等待@products
加载,对象上的每个方法都是异步的,需要将其结果返回回调。这是没有办法的;不能使异步JS代码同步<代码>所有产品
不能只返回值
下面是您应该做的:首先,更改populateProducts
,这样它就不会发出Ajax调用,如果它不需要:
populateProducts : (callback) =>
if @products?
callback()
else ajaxCall (data) =>
@products = data
callback()
然后,只需通过调用@populateProducts
启动使用@products
的每个方法,如下所示:
allProducts : (callback) =>
@populateProducts =>
callback @products
firstProduct: (callback) =>
@populateProducts =>
callback @products[0]
# ...
由于您正在异步加载@products
,并且对象上的每个方法都必须(可能)等待@products
加载,因此对象上的每个方法都是异步的,需要将其结果返回回调。这是没有办法的;不能使异步JS代码同步<代码>所有产品
不能只返回值
下面是您应该做的:首先,更改populateProducts
,这样它就不会发出Ajax调用,如果它不需要:
populateProducts : (callback) =>
if @products?
callback()
else ajaxCall (data) =>
@products = data
callback()
然后,只需通过调用@populateProducts
启动使用@products
的每个方法,如下所示:
allProducts : (callback) =>
@populateProducts =>
callback @products
firstProduct: (callback) =>
@populateProducts =>
callback @products[0]
# ...
啊,去调查一下真是太好了。但愿我永远不必在公共场合说出那个名字。啊,去调查一下真是太好了。但愿我永远不用在公共场合念那个名字。