From c9801d9e5966f390e677c816cf3a38d18063870e Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Tue, 13 Jul 2021 11:30:38 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84buildCachedRegFn?= =?UTF-8?q?=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shared/manager/__tests__/buildRegFn.spec.ts | 13 +++++++ shared/manager/buildRegFn.ts | 41 +++++++++++++++------ shared/utils/is-promise.ts | 7 ++++ 3 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 shared/utils/is-promise.ts diff --git a/shared/manager/__tests__/buildRegFn.spec.ts b/shared/manager/__tests__/buildRegFn.spec.ts index 55f8193a..8be0ea31 100644 --- a/shared/manager/__tests__/buildRegFn.spec.ts +++ b/shared/manager/__tests__/buildRegFn.spec.ts @@ -110,4 +110,17 @@ describe('buildCachedRegFn should be ok', () => { get(); expect(fn.mock.calls.length).toBe(3); }); + + test('should cache promise fn', () => { + const [get, set] = buildCachedRegFn('test'); + const fn = jest.fn(async () => undefined); + set(fn); + + get(); + get(); + get(); + expect(fn.mock.calls.length).toBe(1); + get(1); + expect(fn.mock.calls.length).toBe(2); + }); }); diff --git a/shared/manager/buildRegFn.ts b/shared/manager/buildRegFn.ts index 16cd03da..b35f07c5 100644 --- a/shared/manager/buildRegFn.ts +++ b/shared/manager/buildRegFn.ts @@ -1,5 +1,6 @@ import _isFunction from 'lodash/isFunction'; import _isEqual from 'lodash/isEqual'; +import { isPromise } from '../utils/is-promise'; /** * 构建一对get set 方法 @@ -53,7 +54,7 @@ export function buildRegFnWithEvent any>( /** * 缓存版本的buildRegFn */ -export function buildCachedRegFn Promise>( +export function buildCachedRegFn any>( name: string, defaultFunc?: F ) { @@ -62,17 +63,33 @@ export function buildCachedRegFn Promise>( let _result: any = null; // 缓存的返回值 let _lastArgs: any; - const cachedGet = async (...args: any) => { - if (_result !== null && _isEqual(args, _lastArgs)) { - // 当有缓存的返回值且两次参数一致 - return _result; - } else { - const result = await get(...args); - _result = result ?? null; - _lastArgs = args; - return result; - } - }; + function isSame(args: any[]) { + // 当有缓存的返回值且两次参数一致 + return _result !== null && _isEqual(args, _lastArgs); + } + + // 根据是否为 promise 做区分 + const cachedGet: any = isPromise(get) + ? async (...args: any) => { + if (isSame(args)) { + return _result; + } else { + const result = await get(...args); + _result = result ?? null; + _lastArgs = args; + return result; + } + } + : (...args: any) => { + if (isSame(args)) { + return _result; + } else { + const result = get(...args); + _result = result ?? null; + _lastArgs = args; + return result; + } + }; const refreshCache = () => { _result = null; diff --git a/shared/utils/is-promise.ts b/shared/utils/is-promise.ts new file mode 100644 index 00000000..6198ef84 --- /dev/null +++ b/shared/utils/is-promise.ts @@ -0,0 +1,7 @@ +export function isPromise(obj: any): obj is Promise { + return ( + !!obj && + (typeof obj === 'object' || typeof obj === 'function') && + typeof obj.then === 'function' + ); +}