一、没有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状态 | |
---|---|---|
无catch | reject | fullfilled |
有catch | reject | fullfilled |
2、在resolve或reject中抛出错误:没有catch时会抛到全局,状态变为rejected,有catch时则被捕获,状态变为fullfilled:
后续处理 | promise状态 | |
---|---|---|
无catch | 全局 | rejected |
有catch | catch | fullfilled |
三、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);