Javascript 函数的缓存结果?

Javascript 函数的缓存结果?,javascript,caching,Javascript,Caching,在Javascript中,是否有一种方法可以缓存以下函数的结果: a) 。计算上很昂贵 b) 。打了好几次电话 以频繁调用的递归阶乘函数为例。通常我会创建一个单独的数组,比如facotrialResults=[]并在计算结果时将结果添加到其中,factorialResults[x]=result但是,有没有更好的方法来完成此缓存,而无需向全局命名空间添加新变量?您可以定义自己的函数属性,以便缓存的结果与函数关联,而不是在新数组中填充全局命名空间: function factorial(n)

在Javascript中,是否有一种方法可以缓存以下函数的结果:

  • a) 。计算上很昂贵
  • b) 。打了好几次电话

以频繁调用的递归阶乘函数为例。通常我会创建一个单独的数组,比如
facotrialResults=[]并在计算结果时将结果添加到其中,
factorialResults[x]=result但是,有没有更好的方法来完成此缓存,而无需向全局命名空间添加新变量?

您可以定义自己的函数属性,以便缓存的结果与函数关联,而不是在新数组中填充全局命名空间:

function factorial(n) {
  if (n > 0) {
    if (!(n in factorial))  // Check if we already have the result cached.
      factorial[n] = n * factorial(n-1);
    return factorial[n];
  }
  return NaN;
}
factorial[1] = 1; // Cache the base case.

唯一的问题是检查结果是否已缓存的开销。但是,如果检查的复杂性比重新计算问题要低很多,那么这是非常值得的。

你可以考虑将库滚动到你的环境中。它对很多事情都很有用,包括它的功能

通过缓存计算结果来记忆给定函数。有益于 加速运行缓慢的计算。如果通过了可选的 hashFunction,它将用于计算用于存储 结果,基于原始函数的参数。默认值 hashFunction只将记忆函数的第一个参数用作 钥匙

var fibonacci=\uu0.memoize(函数(n){
返回n<2?n:fibonacci(n-1)+fibonacci(n-2);
});

您可以将哈希附加到要缓存的函数

var expensive_fn = function(val) {
  var result = arguments.callee.cache[val];
  if(result == null || result == undefined) {
    //do the work and set result=...
    arguments.callee.cache[val]=result;
  }
  return result;
}
expensive_fn.cache = {};
这要求函数是1-1函数,没有副作用。

使用缓存

这是一般的解决办法

// wrap cache function
var wrapCache = function(f, fKey){
    fKey = fKey || function(id){ return id; };
    var cache = {};

    return function(key){
        var _key = fKey(key); 
        if (!cache[_key]){
            cache[_key] = f(key);
        };

        return cache[_key];
   };
};

// functions that expensive
var getComputedRGB = function(n){
    console.log("getComputedRGB called", n) ;
    return n * n * n; 
};

// wrapping expensive
var getComputedRGBCache = wrapCache(getComputedRGB, JSON.stringify);


console.log("normal call");
console.log(getComputedRGB(10));
console.log(getComputedRGB(10));
console.log(getComputedRGB(10));
console.log(getComputedRGB(10));
// compute 4 times


console.log("cached call") ;
console.log(getComputedRGBCache(10));
console.log(getComputedRGBCache(10));
console.log(getComputedRGBCache(10));
console.log(getComputedRGBCache(10));
// compute just 1 times


// output
=> normal call 
getComputedRGB called 10
1000
getComputedRGB called 10
1000
getComputedRGB called 10
1000
getComputedRGB called 10
1000

=> cached call
getComputedRGB called 10
1000
1000
1000
1000

it destruct own function我认为缓存函数必须包装自己的函数更好..被调用方不推荐使用ecma5和it destruct own function然后您可以显式引用该函数。
// wrap cache function
var wrapCache = function(f, fKey){
    fKey = fKey || function(id){ return id; };
    var cache = {};

    return function(key){
        var _key = fKey(key); 
        if (!cache[_key]){
            cache[_key] = f(key);
        };

        return cache[_key];
   };
};

// functions that expensive
var getComputedRGB = function(n){
    console.log("getComputedRGB called", n) ;
    return n * n * n; 
};

// wrapping expensive
var getComputedRGBCache = wrapCache(getComputedRGB, JSON.stringify);


console.log("normal call");
console.log(getComputedRGB(10));
console.log(getComputedRGB(10));
console.log(getComputedRGB(10));
console.log(getComputedRGB(10));
// compute 4 times


console.log("cached call") ;
console.log(getComputedRGBCache(10));
console.log(getComputedRGBCache(10));
console.log(getComputedRGBCache(10));
console.log(getComputedRGBCache(10));
// compute just 1 times


// output
=> normal call 
getComputedRGB called 10
1000
getComputedRGB called 10
1000
getComputedRGB called 10
1000
getComputedRGB called 10
1000

=> cached call
getComputedRGB called 10
1000
1000
1000
1000