refactor(3d-situational-awareness): 优化切片集加载流程,引入清理机制与提前退出

新增统一的清理函数,用于处理超时及移除事件监听器。
针对已加载切片引入提前退出检查,从而避免冗余等待。
强化错误处理机制,用于区分超时错误,并确保在 `finally` 块中执行清理操作。
This commit is contained in:
Zzc 2025-11-27 17:12:32 +08:00
parent dc4c88acb5
commit bb5bed014c

View File

@ -87,46 +87,66 @@ export function use3DTiles() {
return return
} }
let timeoutId = null
let eventHandler = null
// 统一清理函数
const cleanup = () => {
if (timeoutId) {
clearTimeout(timeoutId)
timeoutId = null
}
if (eventHandler) {
tileset.initialTilesLoaded.removeEventListener(eventHandler)
eventHandler = null
}
}
try { try {
// 步骤1等待 Tileset 基础就绪 // 步骤1等待 Tileset 基础就绪
await tileset.readyPromise await tileset.readyPromise
console.log('[use3DTiles] Tileset readyPromise 已完成') console.log('[use3DTiles] Tileset readyPromise 已完成')
// 步骤2等待初始瓦片加载完成带超时 // 步骤2早期出口 - 快速检查
if (tileset.tilesLoaded) {
console.log('[use3DTiles] 瓦片已加载,直接继续')
return
}
// 步骤3等待初始瓦片加载完成带超时
console.log('[use3DTiles] 等待初始瓦片加载...') console.log('[use3DTiles] 等待初始瓦片加载...')
await Promise.race([ await Promise.race([
// 等待 initialTilesLoaded 事件 // 等待 initialTilesLoaded 事件
new Promise((resolve) => { new Promise((resolve) => {
const handleInitialTilesLoaded = () => { eventHandler = () => {
console.log('[use3DTiles] 初始瓦片加载完成(事件触发)') console.log('[use3DTiles] 初始瓦片加载完成(事件触发)')
tileset.initialTilesLoaded.removeEventListener(handleInitialTilesLoaded) cleanup()
resolve()
}
tileset.initialTilesLoaded.addEventListener(handleInitialTilesLoaded)
// 如果已经加载完成可能事件已经触发过了直接resolve
// 通过检查tileset.tilesLoaded来判断
if (tileset.tilesLoaded) {
console.log('[use3DTiles] 瓦片已加载,直接继续')
tileset.initialTilesLoaded.removeEventListener(handleInitialTilesLoaded)
resolve() resolve()
} }
tileset.initialTilesLoaded.addEventListener(eventHandler)
}), }),
// 超时机制 // 超时机制
new Promise((resolve) => { new Promise((_, reject) => {
setTimeout(() => { timeoutId = setTimeout(() => {
console.warn(`[use3DTiles] 等待瓦片加载超时(${timeout}ms继续执行`) cleanup()
resolve() reject(new Error(`等待瓦片加载超时(${timeout}ms`))
}, timeout) }, timeout)
}) })
]) ])
console.log('[use3DTiles] Tileset 已完全就绪') console.log('[use3DTiles] Tileset 已完全就绪')
} catch (error) { } catch (error) {
if (error.message && error.message.includes('超时')) {
// 超时但继续执行(保持原有行为)
console.warn(`[use3DTiles] ${error.message},继续执行`)
} else {
console.error('[use3DTiles] 等待 Tileset 就绪失败:', error) console.error('[use3DTiles] 等待 Tileset 就绪失败:', error)
}
// 即使失败也不抛出异常,允许程序继续执行 // 即使失败也不抛出异常,允许程序继续执行
} finally {
cleanup() // 保险清理
} }
} }