zoukankan      html  css  js  c++  java
  • 函数缓存

    一般可用于优化本地请求多次

    // util.ts
    import addSeconds from 'date-fns/add_seconds';
    import getTime from 'date-fns/get_time';
    import request from './ajax'; // 自己封装好的request
    
    /**
     * 创建一个会缓存 func 结果的函数。 如果提供了 resolver ,就用 resolver 的返回值作为 key 缓存函数的结果。
     *  默认情况下用第一个参数作为缓存的 key。 func 在调用时 this 会绑定在缓存函数上。相比 lodash-es 库,增加了异步函数的支持。
     * @memberof module:shared
     * @param {function} fn 需要缓存化的函数
     * @param {function} opt 配置项 resolver: 生成 key , expire: 过期时间,以秒为单位
     * @return {function} 包装后的函数
     * @example
     *
     * const obj = { a: 1, b: 2 }
     * const foo = (obj) => Object.values(obj)
     * const bar = memorize(foo)
     * bar(obj)
     * // [1, 2]
     * obj.a = 10
     * bar(obj)
     * // [1, 2]
     */
    
    function isPromise(value: any): boolean {
      return typeof value === 'object' && value !== null && typeof value.then === 'function';
    }
    
    export interface IMemorizeOptions {
      resolver?: (...value: any[]) => NonNullable<any>;
      expire: number;
    }
    
    export function memorize(
      fn: (...rest: any[]) => any,
      opt: IMemorizeOptions = {
        expire: 60
      }
    ) {
      const cache = new Map();
      const { resolver: hash, expire } = opt;
    
      function setExpire(time: number): number | null {
        return typeof time === 'number' ? getTime(addSeconds(Date.now(), time)) : null;
      }
    
      /* eslint-disable no-nested-ternary */
      function memoized(this: any, ...params: any[]) {
        const key = typeof hash === 'function' ? hash(...params) : params[0];
        const {
          expire: curExpire,
          value: memoizedValue,
          shouldReturnPromise
        }: {
          expire?: number;
          value?: any;
          shouldReturnPromise?: boolean;
        } = cache.get(key) || {};
    
        // 过期数据
        if (typeof curExpire === 'number' && Date.now() > curExpire) {
          cache.delete(key);
        }
    
        if (cache.has(key)) {
          return shouldReturnPromise ? Promise.resolve(memoizedValue) : memoizedValue;
        }
    
        const res = fn.apply(this, params);
    
        if (isPromise(res)) {
          return res.then(
            (value: any) => {
              cache.set(key, {
                value,
                expire: setExpire(expire),
                shouldReturnPromise: true
              });
              return value;
            },
            (err: Error) => Promise.reject(err)
          );
        }
        cache.set(key, {
          value: res,
          expire: setExpire(expire)
        });
        return res;
      }
      memoized.cache = cache;
      return memoized;
    }
    
    export function requestWithCache(options?: IMemorizeOptions) {
      return memorize(request, options);
    }
    
    export default requestWithCache;
    
    
    // 使用
    
    function memoReq() {
      return requestWithCache({
        resolver: (url: string, params?: any) => `${url}_${JSON.stringify(params)}`,
        expire: 60 * 10
      });
    }
    
    const cacheReq = memoReq();
    // apply:
    cacheReq('/v1/xxx.api').then().catch()
    
    
  • 相关阅读:
    专职DBA-MySQL体系结构与基本管理
    JSON
    MIME类型
    文件上传下载
    response常用的方法
    2020.11.27小记
    HTTP请求状态码
    1561. Maximum Number of Coins You Can Get
    1558. Minimum Numbers of Function Calls to Make Target Array
    1557. Minimum Number of Vertices to Reach All Nodes
  • 原文地址:https://www.cnblogs.com/mapleChain/p/15802385.html
Copyright © 2011-2022 走看看