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()
    
    
  • 相关阅读:
    基贝叶斯后验概率的拼写检查器实现 python
    Hadoop The Definitive Guide 2nd Edition 笔记
    DGV删除当前选中行
    DGV设置单元不可编辑
    DGV获取当前选中单元格
    HDU2112_HDU Today_有地名的最短路_map+SPFA
    HDU1026_优先队列+广搜+打印路径
    HDU2757_Ocean Currents_优先队列+广搜_入门题_十四周模拟赛
    自己写的SPFA模板(可打印路径)
    HDU2782_暴力深搜_第十四周模拟赛
  • 原文地址:https://www.cnblogs.com/mapleChain/p/15802385.html
Copyright © 2011-2022 走看看