H5Pay 实例创建时机对比分析
一、两种创建方式
方式一:模块加载时创建(之前的方式)
// 在模块顶层,模块加载时立即创建
const h5Pay = new H5Pay({
env: getAppEnv(),
ubt: UBTHelper.UBT as any,
hbridge: hbridge as any,
systemCode: isWechatMini ? '64' : '63',
token: storeManager.token, // 使用创建时的 token
});
// 在函数中使用
const handlePayment = (payParams: any, returnUrl: string) => {
return h5Pay.pay({
payParams,
// ...
});
};
中间想法:模块加载时创建,但是重新传入token
虽然传入最新 token,但实例是旧的,只是针对方法pay传入了最新的token
// 在模块顶层,模块加载时立即创建
const h5Pay = new H5Pay({
env: getAppEnv(),
ubt: UBTHelper.UBT as any,
hbridge: hbridge as any,
systemCode: isWechatMini ? '64' : '63',
token: storeManager.token, // 使用创建时的 token
});
// 在函数中使用
const handlePayment = (payParams: any, returnUrl: string) => {
return h5Pay.pay({
// !!!虽然传入最新 token,但实例是旧的,只是针对方法pay传入了最新的token
token: storeManager.token,
payParams,
// ...
});
};
方式二:调用时创建(现在的方式)
// 创建实例的函数
const getH5PayInstance = () => {
return new H5Pay({
env: getAppEnv(),
ubt: UBTHelper.UBT as any,
hbridge: hbridge as any,
systemCode: isWechatMini ? '64' : '63',
token: storeManager.token, // 每次创建时使用最新的 token
});
};
// 在函数中使用
const handlePayment = (payParams: any, returnUrl: string) => {
const h5Pay = getH5PayInstance(); // 每次调用时创建新实例
return h5Pay.pay({
payParams,
// ...
});
};
二、方式一:模块加载时创建
✅ 优点
- 性能优势
-
- 实例只创建一次,减少对象创建开销
- 内存占用更少(单例模式)
- 适合频繁调用的场景
- 初始化时机明确
-
- 在模块加载时完成初始化
- 如果初始化失败,会在应用启动时暴露问题
- 便于调试和排查问题
- 代码简洁
-
- 不需要额外的函数封装
- 直接使用常量,代码更直观
❌ 缺点
- 配置可能过期
-
token在创建时固定,后续 token 更新不会反映到实例中- 虽然可以在
pay()方法中传入新 token,但实例本身的配置可能已过期 - 如果 H5Pay 内部缓存了 token,可能导致使用过期 token
- 环境变量固定
-
env、systemCode等在创建时确定- 如果运行时环境变化,实例不会更新
- 例如:从开发环境切换到生产环境
- 路由参数固定
-
isWechatMini在模块加载时判断- 如果用户在不同环境间切换,判断可能不准确
- 内存泄漏风险
-
- 如果 H5Pay 实例持有大量资源或监听器
- 单例模式可能导致资源无法释放
三、方式二:调用时创建
✅ 优点
- 配置始终最新
-
- 每次调用都使用最新的
token - 用户重新登录后,下次支付会使用新 token
- 避免 token 过期导致的支付失败
- 每次调用都使用最新的
- 环境动态适应
-
env、systemCode等每次都是最新值- 适应运行时环境变化
- 更灵活,适合多环境场景
- 路由参数准确
-
isWechatMini在调用时判断,更准确- 适应不同页面、不同环境的需求
- 资源管理更好
-
- 每次创建新实例,旧实例可以被 GC 回收
- 避免长期持有资源导致的内存问题
❌ 缺点
- 性能开销
-
- 每次调用都创建新实例,增加对象创建开销
- 如果支付调用频繁,可能影响性能
- 内存占用可能更多(虽然旧实例会被回收)
- 初始化失败时机不确定
-
- 初始化失败可能在用户支付时才发现
- 用户体验较差(支付时才发现问题)
- 需要更好的错误处理
- 代码复杂度稍高
-
- 需要额外的
getH5PayInstance()函数 - 代码稍微复杂一些
- 需要额外的
四、总结对比表
| 对比项 | 方式一:模块加载时创建 | 方式二:调用时创建 |
|---|---|---|
| 性能 | ✅ 更好(单例,只创建一次) | ⚠️ 稍差(每次创建) |
| 配置准确性 | ❌ 可能过期 | ✅ 始终最新 |
| Token 更新 | ❌ 可能使用旧 token | ✅ 使用最新 token |
| 环境适应 | ❌ 固定 | ✅ 动态适应 |
| 内存占用 | ✅ 更少 | ⚠️ 稍多(但可回收) |
| 代码复杂度 | ✅ 更简单 | ⚠️ 稍复杂 |
| 错误发现时机 | ✅ 启动时 | ❌ 支付时 |
| 适用场景 | 配置不变、高频调用 | 配置可能变化、准确性要求高 |