All files / fn setPromiseCache.ts

100% Statements 15/15
100% Branches 3/3
100% Functions 2/2
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54                                                        4x   5x   3x 3x 16x 8x 8x         5x     5x 5x   8x 8x       1x  
/**
 * 包装为一个缓存函数,限定时间内,返回之前执行的 Promise 结果
 * - 默认在回调执行前多次请求时,返回第一个回调结果
 * - 可实现基于 Promise 机制的防抖能力。
 * @method setPromiseCache
 * @param {Function} fn 返回 Promise 对象的函数
 * @param {Number} cacheTime 数据缓存时间(ms),传负值则为永久缓存
 * @returns {Function} 经过包装的函数
 * @example
 * import { setPromiseCache } from '@spore-ui/tskit';
 * let index = 0;
 * const increase = () => new Promise(resolve => {
 *   setTimeout(() => {
 *     index += 1;
 *     resolve(index);
 *   }, 10);
 * });
 * const cacheIncrease = setPromiseCache(increase);
 * const exec = async () => {
 *   const rs = await cacheIncrease();
 *   console.info(rs);
 * };
 * exec(); // 1
 * exec(); // 1
 */
 
export type TypePromiseFn = (...args: any[]) => Promise<any>;
 
export function setPromiseCache<T extends TypePromiseFn>(
  fn: T,
  cacheTime: number = 0,
): T {
  let pm: Promise<any> = null;
  let startTime: number = null;
  return (async (...args: any[]) => {
    let rs = null;
    const now = new Date().getTime();
    if (
      cacheTime >= 0
      && (now - startTime) > cacheTime
    ) {
      pm = null;
    }
    if (!pm) {
      startTime = new Date().getTime();
      pm = fn(...args);
    }
    rs = await pm;
    return rs;
  }) as T;
}
 
export default setPromiseCache;