Bootstrap

基础总结JS(8):promise中抛出异常

一、没有catch处理函数时:

1、在构造函数中抛出错误,会进入then的reject函数进行结果处理,状态变为:fullfilled

var promise = new Promise((resolve, reject) => {
    throw new Error('nono');  //构造函数同步执行,抛出错误
}).then(()=>{
    console.log('resolve');
},(err)=>{
    console.log('reject');   //执行了
    console.log(err);
});
setTimeout(()=>{
    console.log(promise);   //状态变为fullfilled
}, 0);

在这里插入图片描述

2、在then的resolve处理函数中抛出错误,错误会被抛到全局,状态变为:rejected

var promise = new Promise((resolve, reject) => {
    resolve();
}).then(()=>{
    throw new Error('nono');  //resolve中抛出错误
    console.log('resolve');
},(err)=>{
    console.log('reject'); 
    console.log(err);
});
setTimeout(()=>{
    console.log(promise);
}, 0);

在这里插入图片描述
3、在then的reject处理函数中抛出错误,错误会被抛到全局,状态变为:rejected

var promise = new Promise((resolve, reject) => {
    reject();
}).then(()=>{
    console.log('resolve');
},(err)=>{
    throw new Error('nono');  //resolve中抛出错误
    console.log('reject'); 
    console.log(err);
});
setTimeout(()=>{
    console.log(promise);
}, 0);

在这里插入图片描述

二、有catch处理函数时:

1、在构造函数中抛出错误,会进入then的reject函数进行结果处理,状态变为:fullfilled

var promise = new Promise((resolve, reject) => {
    throw new Error('nono');  //构造函数同步执行,抛出错误
}).then(()=>{
    console.log('resolve');
},(err)=>{
    console.log('reject');    //执行了
    console.log(err);
}).catch((err)=>{
    console.log('catch');     //未执行
    console.log(err);
});
setTimeout(()=>{
    console.log(promise);
}, 0);

在这里插入图片描述

2、在then的resolve处理函数中抛出错误,错误会被catch捕获到,状态变为:fullfilled

var promise = new Promise((resolve, reject) => {
    resolve();
}).then(()=>{
    throw new Error('nono');  //resolve中抛出错误
    console.log('resolve');
},(err)=>{
    console.log('reject'); 
    console.log(err);
}).catch((err)=>{
    console.log('catch');    //执行了
    console.log(err);
});
setTimeout(()=>{
    console.log(promise);
}, 0);

在这里插入图片描述
3、在then的reject处理函数中抛出错误,错误会被catch捕获到,状态变为:fullfilled

var promise = new Promise((resolve, reject) => {
    reject();
}).then(()=>{
    console.log('resolve');
},(err)=>{
    throw new Error('nono');  //resolve中抛出错误
    console.log('reject'); 
    console.log(err);
}).catch((err)=>{
    console.log('catch');    //执行了
    console.log(err);
});
setTimeout(()=>{
    console.log(promise);
}, 0);

在这里插入图片描述

总结:

1、在构造函数中抛出错误:无论是否有catch,都会进入reject处理,状态变为fullfilled(注意不是rejected)

后续处理promise状态
无catchrejectfullfilled
有catchrejectfullfilled

2、在resolve或reject中抛出错误:没有catch时会抛到全局,状态变为rejected,有catch时则被捕获,状态变为fullfilled:

后续处理promise状态
无catch全局rejected
有catchcatchfullfilled

三、throw抛出错误会阻塞后续执行

var promise = new Promise((resolve, reject) => {
    throw new Error('nono');   //阻塞resolve()执行,直接进入reject处理
    resolve();                 //没有执行
}).then(()=>{
    console.log('resolve');    //没有执行
},(err)=>{
    console.log('reject');     //执行了
    console.log(err);
}).catch((err)=>{
    console.log('catch');
    console.log(err);
});
setTimeout(()=>{
    console.log(promise);
}, 0);

在这里插入图片描述

var promise = new Promise((resolve, reject) => {
    resolve();                  //阻塞后面抛出错误
    throw new Error('nono');    //没有执行
}).then(()=>{
    console.log('resolve');     //执行了
},(err)=>{
    console.log('reject'); 
    console.log(err);
}).catch((err)=>{
    console.log('catch');
    console.log(err);
});

在这里插入图片描述

四、在构造函数中将抛出错误语句放在定时器里,catch捕获不到

这会将抛出错误放在事件队列宏任务中,promise是pending状态,后续将都不执行;查找主栈和事件队列微任务,发现都没有执行任务,最后执行宏任务setTimeout里的代码,在全局抛出错误。

var promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        throw new Error('nono'); 
    }, 500);
}).then(()=>{
    console.log('resolve');
},(err)=>{
    console.log('reject'); 
    console.log(err);
}).catch((err)=>{
    console.log('catch');
    console.log(err);
});
setTimeout(()=>{
    console.log(promise);
}, 1000);

在这里插入图片描述

;