结合_.记住和_.节流以限制函数调用,并在一个时间窗口内缓存结果

Combining _.memoize and _.throttle to limit function calls and cache a result within a time window?

本文关键字:一个 窗口 结果 缓存 时间 结合 函数调用      更新时间:2023-09-26

使用一个函数进行一系列调用来返回一个结果,而这个函数在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/