结合_.记住和_.节流以限制函数调用,并在一个时间窗口内缓存结果
Combining _.memoize and _.throttle to limit function calls and cache a result within a time window?
使用一个函数进行一系列调用来返回一个结果,而这个函数在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
只触发设定约束内的函数,不返回所包含函数的输出
我用了_。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
根据下划线来源,它看起来像_。throttle和_.debounce DO返回最后一次计算的结果。所以,他们已经做了你想要的。
memoize不会过期,无论参数如何,throttling都会返回相同的值。
这是throttle和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);
http://jsfiddle.net/6kq4rt0b/相关文章:
- 用javascript将数据从一个窗口传递到另一个窗口
- 创建一个方法,通过一个窗口进行迭代并获取Titanium中的所有控件
- 从另一个窗口访问document.getElementById
- notify.js没有'如果另一个窗口被聚焦,则不显示通知
- 使用YUI或ExtJS将隐藏的DIV变成一个窗口
- 从另一个窗口对链接触发单击事件
- Atom Electron:在另一个窗口中渲染画布
- 使用Javascript单击选择按钮时,在另一个窗口上显示图像
- Javascript/Jquery如何在另一个窗口中检测点击
- 用JavaScript打开一个新窗口,然后关闭前一个窗口
- 使用Javascript/jQuery在当前窗口后面打开一个窗口
- 从另一个窗口调用 iframe
- 在系统焦点使用Electron的地方打开一个窗口
- 将图像数组从一个窗口传递到另一个窗口,并在javascript的新窗口中显示图像
- 一键在一个窗口中打开两个不同的链接图像
- IE10在打开窗口并再次打开另一个窗口时不起作用
- 你怎么知道javascript是否无法打开一个窗口
- 使用 javascript 打开一个窗口,并从外部源加载 HTML 内容
- 仅在一个窗口中播放声音,该窗口使用javascript(可能是jquery)处于活动状态(在一个网站内)
- 用钛将一个窗口移动到另一个窗口