try-catch 的核心价值在于阻断异常传播链而非创建作用域,它使错误止步于 catch 块内,避免全局状态(如 currentuser、loadingstate)陷入中间态;应为每个异步任务单独包裹、配合快照与 finally 清理,确保状态可控。

巧用 try-catch 的块级隔离特性,核心在于理解它**不改变变量作用域,但能切断异常传播链**——异常被 catch 拦下后,就不会继续向上冒泡影响外层逻辑,也就不会干扰页面中正在使用的动态全局变量(比如 currentUser、loadingState、errorMap 等)。关键不是“隔离变量”,而是“隔离错误影响范围”。
明确 try-catch 不改变作用域,但能阻断错误传播
try-catch 本身不会创建新的词法作用域(var 声明仍会提升,let/const 仍是块级),但它让异常止步于 catch 块内。这意味着:
- 你在 try 块里修改了全局变量
window.appStatus = 'pending',即使后续抛错,这个赋值已生效;但如果你在 catch 里主动重置或补偿,就能避免状态残留 - 如果没加 try-catch,一个未捕获的 Promise rejection 或同步报错,可能跳过后续初始化逻辑,导致全局变量停留在中间态(如
user = null却没触发登出流程) - catch 后不 re-throw,就等于“消化”了这次失败,外层代码照常执行,全局状态可由你可控地修复
在异步调用前主动“快照 + 隔离”关键状态
对易受干扰的全局变量,不要等出错后再补救,而是在异步操作启动前做轻量快照,并在 catch 中恢复或兜底:
- 记录当前状态:比如
const prevUser = {...currentUser}、const prevLoading = loadingState.value - 在 try 块中更新状态(如设为 loading)、发起请求
- 在 catch 中还原快照或设置安全默认值:
currentUser = prevUser或loadingState.value = 'idle' - 避免直接修改原始引用对象,优先用解构或深拷贝(简单场景用
{...obj}即可)
为每个独立异步任务单独包裹,防止连锁污染
多个异步操作共用同一组全局变量时,若混在一个 try 块里,前一个失败会导致后一个完全跳过,状态更新断裂。正确做法是:
- 每个异步调用(尤其是更新不同模块状态的)各自用 try-catch 包裹
- 例如:更新用户资料、刷新 token、拉取通知 —— 三个操作应分别 try,失败互不影响
- 这样即使 token 刷新失败,用户资料更新仍可完成,全局
currentUser不会被意外清空 - 配合
Promise.allSettled()可批量发起并独立处理结果,比Promise.all()更安全
在 finally 中统一清理,而非依赖 catch 补偿
finally 是执行收尾最可靠的位置,尤其适合重置副作用状态:
- 关闭 loading 动画、隐藏 skeleton、释放临时锁标识
- 清除定时器、移除事件监听器(避免内存泄漏引发后续状态错乱)
- 注意:finally 中不要 return 或 throw,否则会覆盖 try/catch 的返回值或错误
- 例如:
finally { loadingState.value = 'idle'; abortController?.abort(); }











