[JavaScript] promise.then(...).catch(...)

以下三种情况中promise会报错:Uncaught (in promise) 123

new Promise((resolve,reject)=>{
    reject(123);
});

new Promise((resolve,reject)=>{
    throw 123;
});

Promise.reject(123);

为了捕获promise中的错误,我们可以使用catch方法。

Promise.reject(123).catch(v=>{
    console.warn(v);
});

但是也可以使用

Promise.reject(123).then(v=>{
    console.log(v);
}).catch(v=>{
    console.warn(v);
});

我们知道,Promise.reject(123)会返回一个promise,
then函数会返回一个新的promise
那么catch为什么还能捕获到前面reject的promise呢?

原因在于then函数返回的promise有可能延续之前的promise状态“[[PromiseStatus]]`

The then() method returns a Promise.
It takes up to two arguments: callback functions for the success and failure cases of the Promise.

**Note: **
(1)If both arguments are omitted, or are provided non-functions, a new Promise is created with no additional handlers, simply adopting the final state of the Promise that then is called on.
(2)If the first argument is omitted or provided a non-function, the new Promise that is created simply adopts the fulfillment state of the Promise that then is called on (if it becomes fulfilled).
(3)If the second argument is omitted or provided a non-function, the new Promise that is created simply adopts the rejection state of the Promise that then is called on (if it becomes rejected).

The catch() method returns a Promise and deals with rejected cases only. It behaves the same as calling Promise.prototype.then(undefined, onRejected.

Promise.reject(123)  // { [[PromiseStatus]]:"rejected", [[PromiseValue]]:123 }
.then(v=>{
    console.log(v);
})                   // { [[PromiseStatus]]:"rejected", [[PromiseValue]]:123 }
.catch(v=>{
    console.warn(v);
                     // 没有return,相当于return undefined;
});                  // { [[PromiseStatus]]:"resolved", [[PromiseValue]]:undefined }

注:
promise.then(...).catch(...);promise.then(..., ...);不等价
尤其注意当promise.then(...).catch(...);中的then会抛异常的情况下。

promise
    .then(...)    //返回一个新的promise,如果then之前的promise是rejected则延续
    .catch(...);    //又返回一个新的promise,如果catch之前的promise是resolved则延续

promise
    //返回一个新的promise
    //如果then之前的promise是resolved,则由第一个参数返回
    //如果then之前的promise是rejected,则由第二个参数返回。
    .then(..., ...);    

例子:

const fn = () => {
    throw 2;
}

//promise.then(...).catch(...);
Promise.resolve(1)         //{ [[PromiseStatus]]:"resolved", [[PromiseValue]]:1 }
    .then(v => {           //1
        fn();              //抛异常了,then返回一个rejected的promise
        return 3;          //后面不执行了
    })                     //{ [[PromiseStatus]]:"rejected", [[PromiseValue]]:2 }
    .catch(v => {          //v是throw的值2
        console.log(v);    //2
        return 4;          //catch返回一个resolved且值为4的promise
    });                    //{ [[PromiseStatus]]:"resolved", [[PromiseValue]]:4 }
//程序最后正常结束

//promise.then(..., ...);
Promise.resolve(1)         //{ [[PromiseStatus]]:"resolved", [[PromiseValue]]:1 }
    .then(
        v => {             //1
            fn();          //抛异常了,then返回一个rejected的promise
            return 3;      //后面不执行了
        },
        v => {             //这里只有then之前是rejected才执行
            console.log(v);//不执行
            return 4;      //不执行
        }
    );                     //{ [[PromiseStatus]]:"rejected", [[PromiseValue]]:2 }
//程序最后抛异常:Uncaught (in promise) 2

参考
Promise.prototype.then()
Promise.prototype.catch()

点赞