Skip to content

提供额外方法的momerize方法

常用的js库lodash提供了一个给函数提供缓存特性的memorize方法,不过在实际使用中功能还不足以满足复杂需求,所以自己写了以下memorize方法:

typescript
/**
 * This function memoizes a function and returns a new memoized function.
 * @param fn The function to memoize.
 * @param config The configuration for the memoization.
 * @param config.maxAge The maximum age of the cache in milliseconds.
 */
export const memorize = (fn: Function, config?: { maxAge: number }) => {
  let maxAge = (config && config.maxAge) || 0;
  const cache = new Map();

  const memoizedFn = (...args: any[]) => {
    const key = JSON.stringify(args);

    // Check if the result is in the cache and is not expired.
    if (cache.has(key) && (!maxAge || cache.get(key).expires > Date.now())) {
      return cache.get(key).result;
    }

    const result = fn(...args);
    cache.set(key, { result, expires: Date.now() + (maxAge || 0) });
    return result;
  };

  /**
   * Returns the configuration for the memoized function.
   */
  memoizedFn.config = { maxAge };

  /**
   * Sets the configuration for the memoized function.
   */
  memoizedFn.setConfig = (newConfig: { maxAge: number }) => {
    maxAge = newConfig.maxAge;
  };

  /**
   * Clears the cache for the memoized function. If no arguments are passed, clears the entire cache.
   * If arguments are passed, clears the cache for those arguments.
   */
  memoizedFn.clearCache = (...args: any[]) => {
    if (!args.length) {
      cache.clear();
      return;
    }

    const key = JSON.stringify(args);
    cache.delete(key);
  };

  /**
   * Returns the cache for the memoized function.
   */
  memoizedFn.cache = cache;

  /**
   * Runs the memoized function with the given arguments and clears the cache before and after.
   */
  memoizedFn.runWithClear = (...args: any[]) => {
    memoizedFn.clearCache(...args);
    const result = memoizedFn(...args);
    return result;
  };

  return memoizedFn;
};

const fibonacci = memorize((n: number) => {
  if (n <= 1) {
    return n;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
});

在使用时除了memorizedFn(args)这样常规运行,还可以通过memorizedFn.runWithClear(args)来强制刷新缓存来运行。
以及在一开始包装函数时设置最大过期时间,执行时根据是否过期来动态决定是否刷新缓存。