使用一个函数调用一系列调用来返回一个结果,该结果在Angular模板中一次多次请求。在这些请求期间,结果不会改变,因此在函数内部进行额外调用的开销是不必要的。
是否可以在一定的等待时间内创建一个缓存并返回相同结果的限制函数?
与下面的简化示例一致。
var throttleCache = _.memoizeThrottle(function() {
return _.now();
}, 100);
_.delay(throttleCache, 0); // now + 0ms
_.delay(throttleCache, 10); // now + 0ms
_.delay(throttleCache, 99); // now + 0ms
_.delay(throttleCache, 101); // now + 101ms
_.delay(throttleCache, 150); // now + 101ms
据我所知,_.memoize
根据参数无限期地缓存结果,无法定时自动刷新此缓存。并且_.throttle
和_.debounce
仅在集合约束内触发函数,但不返回包含函数的输出。
答案 0 :(得分:2)
我使用_.memoize方法扩展它并添加一个ttl参数,以强制在过期时重新计算值。
#!/usr/bin/env coffee
_=require 'underscore'
# Memoize an expensive function by storing its results.
# After ttl time, the value will be recomputed
memoinesic = (func, hasher=_.identity, ttl=0)->
memoize = ()->
cache = memoize.cache
key = hasher.apply(@,arguments)
now = Date.now()
if !_.has(cache,key) or now>cache[key].expires
cache[key] =
value: func.apply(@,arguments)
expires: now+ttl
cache[key].value
memoize.cache = {}
memoize
_.mixin(memoinesic:memoinesic)
# Let's try it!
appendToNow = _.memoinesic(
(x)-> "#{x}:#{Date.now()}",
null,
1000
)
logTimedFoo = _.compose console.log,_.partial appendToNow,'foo'
logTimedFoo()
setInterval logTimedFoo,200
答案 1 :(得分:0)
根据underscorejs source,看起来_.throttle和_.debounce都会返回上次计算的结果。就这样,他们已经做了你想做的事。
答案 2 :(得分:0)
memoize不会过期,并且不管参数如何,throttled都会返回相同的值。
这是节流和memoize的组合,以获得一个记忆版本的功能,该功能将在固定的持续时间后重新计算。
// tester to get a combinaison of throttle and memoize.
var _ = require('lodash');
var start = Date.now();
var func = function(text) {
var toDisplay = "argument " + text + " at " + (Date.now() - start);
console.log("executed with", toDisplay);
return toDisplay;
};
var getCachedFunc = function(myFuncToCache, cacheDuration, context) {
// we need to return a different throttled function for each different parameters so memoize it
var memoizedFunction = _.memoize(function() {
var myFuncToCacheArguments = arguments;
var throttledFunc = _.throttle(myFuncToCache, cacheDuration, {trailing: false});
return function executeThrottledFunction() {return throttledFunc.apply(null, myFuncToCacheArguments);};
});
return function applyMemoizedFunction() {
// apply the throttled function
return memoizedFunction.apply(context, arguments)();
};
};
var myCachedFunc = getCachedFunc(func, 4000);
var callWithArgument1 = function() {
console.log("calling with argument 1 at " + (Date.now() - start));
console.log("returned",myCachedFunc('1'));
};
var callWithArgument2 = function() {
console.log("calling with argument 2 at " + (Date.now() - start));
console.log("returned",myCachedFunc('2'));
};
callWithArgument1();
setTimeout(function() {callWithArgument1();}, 2000);
setTimeout(function() {callWithArgument2();}, 2200);
setTimeout(function() {callWithArgument1();}, 5000);