You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何同时使用Promise的.then与.catch时控制台报错,仅用.catch则无报错?

Promise Reject捕获异常问题解析

问题代码

let condition=false;

let p1=new Promise((resolve,reject)=>{
    console.log("p1 is pending");
    setTimeout(()=>{
        if(condition){
            console.log("p1 resolved");
            resolve("i resolved");
        }
        else{
            console.log("p1 rejected");
            reject("i rejected");
        }
    },3000);
});


p1.then((returned_val)=>{
    console.log(".then-> p1 returned :",returned_val);
})
p1.catch((returned_val)=>{
    console.log(".catch-> p1 returned :",returned_val);
});

问题描述

当condition为false时,Promise执行reject操作。仅单独使用.catch时控制台无错误,但同时使用.then和.catch时控制台却出现未处理的Promise错误,原因是什么?

原因解析

核心问题在于你给同一个Promise实例p1分别单独挂载了.then和.catch,而非使用链式调用:

  • 当p1被reject时,你单独调用的.then(只传入了成功回调)会返回一个新的被reject的Promise实例,而这个新实例没有被任何.catch或错误回调处理,所以浏览器会抛出未处理的Promise rejection错误。
  • 你挂载在p1上的.catch确实捕获了原Promisep1的reject,但.then返回的新Promise的reject状态完全独立,没有被处理,因此控制台依然会报错。

你的写法等价于:

// 单独挂载then,返回未被处理的rejected Promise
const p2 = p1.then(/* 成功回调 */);
// 单独挂载catch到原p1
const p3 = p1.catch(/* 失败回调 */);
// p2的reject未被处理,触发控制台报错

正确写法

链式调用(推荐)

让.catch捕获整条Promise链上的所有未处理异常:

p1.then((returned_val) => {
    console.log(".then-> p1 returned :", returned_val);
}).catch((returned_val) => {
    console.log(".catch-> p1 returned :", returned_val);
});

给.then传入失败回调

直接在.then的第二个参数中处理reject,避免产生未处理的新Promise:

p1.then((returned_val) => {
    console.log(".then-> p1 returned :", returned_val);
}, (returned_val) => {
    console.log(".catch-> p1 returned :", returned_val);
});

内容的提问来源于stack exchange,提问作者Arun Panigrahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:20:31