TypeScript
/*
* @Date: 2024-12-10 15:59:32
* @Description: 加载异步代码
*/
import { type Type, type ReversedType, type ReversedTypeRecord } from '@/lazy/type'
type Key = keyof Type
/** 只支持调用函数 */
export const lazierInit = new Proxy<ReversedType>({} as any, {
get<T extends Key>(_, key: T): Promise<ReversedTypeRecord[T]['value']> {
return <Promise<ReversedTypeRecord[T]['value']>><unknown>function (...args) {
return new Promise((resolve) =>{
/** @ts-ignore */
resolve(require.async("../../../lazy/type.js"))
}).then((res) => {
const {type : reversedType} = res as { type: Type }
if (typeof reversedType[key] !== 'function') {
return ''
}
return (reversedType[key] as (...arg: any[]) => any).call(this,...args)
}).catch(err => {
wx.$.collectEvent.event("lazyFalse", {
key: key,
data: JSON.stringify(err)
})
return Promise.reject(err)
})
}
}
})
/** 支持直接访问常量(如数组)和调用函数
*
* // 1. 调用函数(带参数)
*await wx.$.l.operationMidCallV3(arg1, arg2);
*
* // 2. 访问常量数组
*const shouldShow = (await wx.$.l.newResumeMidPops1()).includes('call_B');
*
* // 3. 更简洁的常量访问方式(无参数调用)
* const arr = await wx.$.l.newResumeMidPops1();
*
* // 4.需要将组件的实例this等 一起带给方法
* wx.$.l.callPhoneBtnOfList.call(this, e.detail, { ... })
*
*/
const moduleCache: { [key: string]: any } = {};
export const lazier = new Proxy({} as any, {
get<T extends string>(_: any, key: T) {
return function (this: any, ...args: any[]) {
return (async () => {
if (!moduleCache[key]) {
try {
const res = await new Promise<any>((resolve) => {
/** @ts-ignore */
resolve(require.async("../../../lazy/type.js"));
});
const { type: reversedType } = res as { type: any };
moduleCache[key] = reversedType[key];
} catch (err) {
wx.$.collectEvent.event("lazyFalse", { key, data: JSON.stringify(err) });
throw err;
}
}
const cachedValue = moduleCache[key];
if (typeof cachedValue === 'function') {
return cachedValue.apply(this, args);
}
return cachedValue;
})();
};
}
});
---------------避免用户使用程序的过程中,缓存无限增大,内存泄露。
- 结合缓存过期时间和LRU(最近最少使用)策略,确保缓存的有效性和内存使用效率。
继续优化:
TypeScript
interface CacheItem {
value: any;
expires: number;
}
const MAX_CACHE_SIZE = 1000;
const moduleCache: { [key: string]: CacheItem } = {};
const cacheOrder: string[] = [];
function addToCache(key: string, value: any) {
if (cacheOrder.length >= MAX_CACHE_SIZE) {
const oldestKey = cacheOrder.shift();
if (oldestKey) {
delete moduleCache[oldestKey];
}
}
moduleCache[key] = { value, expires: Date.now() + 60000 }; // 设置1分钟过期时间
cacheOrder.push(key);
}
export const lazier = new Proxy({} as any, {
get<T extends string>(_: any, key: T) {
return function (this: any, ...args: any[]) {
return (async () => {
const now = Date.now();
if (!moduleCache[key] || moduleCache[key].expires < now) {
try {
const res = await new Promise<any>((resolve) => {
/** @ts-ignore */
resolve(require.async("../../../lazy/type.js"));
});
const { type: reversedType } = res as { type: any };
addToCache(key, reversedType[key]);
} catch (err) {
wx.$.collectEvent.event("lazyFalse", { key, data: JSON.stringify(err) });
throw err;
}
}
const cachedValue = moduleCache[key].value;
if (typeof cachedValue === 'function') {
return cachedValue.apply(this, args);
}
return cachedValue;
})();
};
}
});