type CachePromiseFun<T> = (...args: any[]) => Promise<T>
interface PromiseCacheSingletonOptions {
export const promiseCacheSingleton = <T>(
promiseFun: CachePromiseFun<T>, {
}: PromiseCacheSingletonOptions = {}
): CachePromiseFun<T> => {
if (!promiseFun || typeof promiseFun !== 'function') {
throw new Error('The current params "promiseFun" must be function')
// expries 不应该是 0,是 0 其实没有意义,直接报错
throw new Error('The current params "expries" must be greater than 0')
let currentPendingPromise: Promise<T> | null = null
let preTimeoutHandler: number | null = null
let preArgsStr: string = ''
return async (...args: any[]) => {
// 不跳过参数对比,就进行比对以及删除上一个缓存
const currentArgsStr: string = JSON.stringify(args)
// 如果参数不等,直接删除当前的 Promise 缓存,再次进行请求
if (preArgsStr !== currentArgsStr) {
currentPendingPromise = null
window.clearTimeout(preTimeoutHandler)
preArgsStr = currentArgsStr
// 当前有正在 pending 的 Promise 对象,直接返回
if (currentPendingPromise) {
return currentPendingPromise
currentPendingPromise = promiseFun(...args)
let value: T | null = null
value = await currentPendingPromise
currentPendingPromise = null
preTimeoutHandler = window.setTimeout(() => {
currentPendingPromise = null