Promise错误处理优化需确保错误不漏、不乱、不藏:明确传播链、分层捕获(底层转错、中层日志、上层决策)、善用allSettled、禁用同步try-catch误捕异步错误。

Promise 错误处理优化的关键,在于让错误不漏、不乱、不藏,同时保持业务逻辑清晰。不是加个 .catch() 就算完成,而是要结合传播路径、捕获时机和分层策略来设计。
明确错误传播链,避免“断链”
Promise 错误会沿链向下传递,直到遇到第一个 .catch() 或 .then(null, rejectFn)。如果中间某个 .then() 没返回 Promise,或者抛出新错误但没被接住,就可能中断传播。
- 每个
.then()的成功回调里,若需继续异步操作,务必显式返回 Promise(比如return fetch(...).then(...)) - 避免在
.then()中写同步报错(如if (!data) throw new Error(...)),这类错误会被自动转为 rejected,但必须确保后续有捕获点 - 不要在链中间“吞掉”错误却不处理——例如只写
.catch(() => {})而不记录或上报,等于掩盖问题
统一入口 + 分层捕获
把错误处理按职责拆开:底层专注转换错误,中层做分类和日志,上层决定用户可见行为(重试、降级、提示)。
- 网络请求封装层:对 HTTP 状态码做标准化判断,
!response.ok时主动reject(new HttpError(...)),并带上 status、url 等上下文 - 业务逻辑层:用
.catch()区分错误类型(如instanceof NetworkErrorvsinstanceof ValidationError),分别处理 - UI 层:不直接处理原始 error 对象,而是接收业务层返回的结构化结果(如
{ success: false, code: 'TIMEOUT', message: '请稍后重试' })
善用 Promise.allSettled 替代 Promise.all
当多个并行请求中允许部分失败时,Promise.all 一拒全拒,反而增加容错难度;Promise.allSettled 返回每个 Promise 的终态,更利于精细化控制。
- 适用场景:加载用户信息、头像、通知三项数据,其中一项失败不影响其余展示
- 写法示例:
Promise.allSettled([fetchUser(), fetchAvatar(), fetchNotices()]),然后遍历结果数组,对status === 'fulfilled'取值,'rejected'记录日志或打点 - 注意它不改变原有 Promise 状态,不会触发链式
.catch(),所以错误仍需在各子 Promise 内部或结果处理中显式处理
避免 try-catch 误用
try...catch 只能捕获同步错误,对 Promise 内部异步抛出的错误无效。常见错误写法:
-
try { fetchData().then(...).catch(...) } catch (e) { ... }→ 失效,因为fetchData()立即返回 Promise,不抛异常 - 正确做法:错误必须在 Promise 链内捕获,或在
async/await函数中配合try/catch - 混合使用时注意:在
async函数中,await promise后的throw才会被外层try/catch捕获;而promise.then(...)仍需自己.catch()

















