使用带有underscore.js的memoize函数

12

我正尝试使用Underscore.js中的memoize函数缓存一个ajax调用的结果。我不确定我的实现是否正确,也不知道如何使用键检索缓存的结果数据。以下是我的实现代码:

Javascript 代码:

var cdata = $http
.get(HOST_URL + "/v1/report/states")
.success(function(data) {
    //put the result in the angularJs scope object. 
    $scope.states = data;
});

//store the result in the cache.
var cachedResult = _.memoize(
    function() {
        return cdata;
    }, "states");

我使用记忆化技术将ajax的结果存储起来是正确的吗?一旦放入缓存中,如何根据关键字检索它,例如"states"。

3个回答

35

让我们了解一下 _.memoize 的工作原理,它接受一个需要进行记忆化的函数作为第一个参数,并缓存该函数返回给定参数的结果。下次如果使用相同的参数调用记忆化的函数,它将使用缓存的结果,从而避免执行函数的时间。因此,减少计算时间非常重要。

如上所述,当参数具有基本类型时,上面的斐波那契函数可以完美地进行记忆化。

问题出现在必须对接受对象的函数进行记忆化时。为了解决这个问题,_.memoize 接受一个可选参数 hashFunction,用于对输入进行哈希处理。这样,您就可以使用自己的哈希函数来唯一标识自己的对象。

_.memoize 的默认实现(使用默认哈希函数)将第一个参数按原样返回 - 在 JavaScript 的情况下,它将返回 [Object object]

例如:

var fn = function (obj){ some computation here..}
var memoizedFn = _.memoize(fn);

memoizedFn({"id":"1"}) // we will get result, and result is cahced now

memoizedFn({"id":"2"}) // we will get cached result which is wrong

为什么在_.memoize中默认的函数是function(x) {return x}。

通过传递一个哈希函数可以避免这个问题。

_.memoize(fn, function(input){return JSON.stringify(input)});

当我在使用_.memoize对数组参数进行操作的函数时,这真的帮了我很大忙。

希望这能帮助许多人工作。


修正了一些语法错误并添加了一些额外的信息。 - Flame_Phoenix

5

_.memoize 接受一个函数:

var fibonacci = _.memoize(function(n) {
  return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2);
});

你应该明白这只是一个额外的包装函数,可以使你传递给它作为参数的函数更加智能(添加额外的映射对象)。在上面的示例中,计算斐波那契数的函数被包装在_.memoize中。因此,在每个函数调用(fibonacci(5)fibonacci(55555))中,传递的参数与返回值匹配,因此如果您需要再次调用fibonacci(55555),它不需要重新计算,只需从_.memoize内部提供的映射对象获取该值即可。

警告:调用 fibonacci(x) 时例子存在无限递归! - Mouneer

-2
如果你正在使用Angular.js的$http,你可能只想将{cache:true}作为第二个参数传递给get方法。
要使用键值对存储值,你可能想使用$cacheFactory,就像这里中描述的那样。基本上是这样的:
var cache = $cacheFactory('cacheId');
cache.put('states', 'value');
cache.get('states');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接