hookehuyr

refactor(离线缓存): 优化网络监听器注销逻辑并添加注释

确保网络监听器注销时的状态闭环
添加详细的类型定义和代码注释
/*
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-17 00:22:34
* @LastEditTime: 2026-01-17 12:14:16
* @FilePath: /xyxBooking-weapp/src/app.js
* @Description: 应用入口文件
*/
......@@ -168,6 +168,7 @@ const App = createApp({
* - 尝试在网络可用时预加载离线预约数据
* - 启动离线预约缓存轮询(会自行处理网络可用性与引用计数)
*/
const bootstrap_after_auth = () => {
try_preload_when_online()
enable_offline_booking_cache_polling({ interval_ms: 2 * 1000 * 60 })
......@@ -184,6 +185,8 @@ const App = createApp({
* - 授权成功后调用 bootstrap_after_auth 启动共用逻辑
* - 授权失败则跳转至授权页面
*/
// 如果用户已授权,则直接调用 bootstrap_after_auth 启动共用逻辑
if (hasAuth()) {
bootstrap_after_auth()
return
......
......@@ -8,6 +8,7 @@ import { get_network_type, is_usable_network } from '@/utils/network'
/**
* @description: 轮询状态
* @typedef {Object} PollingState
* @property {Number} timer_id 轮询定时器id
* @property {Boolean} running 是否正在轮询
* @property {Boolean} in_flight 是否正在刷新
......@@ -20,6 +21,7 @@ import { get_network_type, is_usable_network } from '@/utils/network'
* @property {Promise} network_listener_promise 网络监听器Promise
*/
/** @type {PollingState} */
const polling_state = {
timer_id: null, // 轮询定时器id
running: false, // 是否正在轮询
......@@ -157,19 +159,31 @@ const ensure_network_listener = async () => {
/**
* @description: 注销网络监听器
* 涉及字段:
* - has_network_listener:是否有注册网络监听器
* - ref_count:引用计数
* - network_listener:网络状态变化监听器
* - network_usable:网络可用性状态
*/
const teardown_network_listener = () => {
// 1. 前置校验:避免无效执行
// 如果没有注册网络监听器,直接返回
if (!polling_state.has_network_listener) return
// 如果有引用计数,说明有其他地方在使用轮询,不能注销监听器
if (polling_state.ref_count > 0) return
// 标记监听器已注销(核心状态更新)
polling_state.has_network_listener = false
// 解绑框架层面的监听器
if (polling_state.network_listener && typeof Taro.offNetworkStatusChange === 'function') {
try {
Taro.offNetworkStatusChange(polling_state.network_listener)
} catch (e) {
polling_state.network_listener = null
// 捕获解绑失败的异常(比如监听器已被手动解绑)
console.warn('注销网络监听器失败:', e)
}
}
// 手动清空本地引用(关键!无论解绑成功/失败都要做)
// 注销后,清空网络监听器引用,确保后续调用能正常工作
polling_state.network_listener = null
/**
......@@ -178,6 +192,7 @@ const teardown_network_listener = () => {
* 设计思维:体现了 “状态闭环” 的工程化思想 —— 任何状态都要有明确的产生、更新、销毁逻辑,不残留 “脏数据” 干扰后续流程。
*/
// 清空网络可用性状态,确保后续判断逻辑能正常工作
// 清空衍生状态,避免脏数据
polling_state.network_usable = null
}
......