关于Promise链式调用(含then/catch)执行结果的疑问
Promise链式调用常见问题解答
代码与执行结果
示例代码
function job(state) { return new Promise(function(resolve, reject) { if (state) { resolve('success'); } else { reject('error'); } }); } let promise = job(true); promise .then(function(data) { ///1 console.log(data); return job(true); }) .then(function(data) { ///2 if (data !== 'victory') { throw 'Defeat'; } return job(true); }) .then(function(data) { ///3 console.log(data); }) .catch(function(error) { ///4 console.log(error); return job(false); }) .then(function(data) { ///5 console.log(data); return job(true); }) .catch(function(error) { ///6 console.log(error); return 'Error caught'; }) .then(function(data) { ///7 console.log(data); return new Error('test'); }) .then(function(data) { ///8 console.log('Success:', data.message); }) .catch(function(data) { ///9 console.log('Error:', data.message); });
执行输出
success Defeat error Error caught Success: test
困惑点解答
1. 为何then3、then4、then5被跳过,转而执行catch6?
Promise链式调用的核心逻辑是:一旦链中出现rejected状态的Promise或抛出异常,会直接跳过后续所有then,直到找到第一个能捕获该异常的catch。
具体流程拆解:
- then2中抛出
'Defeat',Promise状态变为rejected,跳过then3,进入第一个catch(catch4)。 - catch4执行时打印
'Defeat',随后返回job(false)——这个调用会生成一个rejected状态的Promise(因为参数为false)。 - 此时Promise链的状态仍为rejected,因此跳过后续的then5,继续寻找下一个可捕获异常的catch,也就是catch6,最终执行catch6并打印
'error'。
2. then7返回了Error,为何执行then8而非catch9?
Promise的then方法中,只有抛出异常或返回rejected状态的Promise时,才会触发后续的catch。
then7中是return new Error('test')——这只是返回了一个Error类型的对象,既没有抛出异常,也没有返回rejected状态的Promise,此时Promise状态为resolved,值就是这个Error对象,因此会进入下一个then(then8),而非catch9。
如果要触发catch9,需要改成以下两种方式之一:
// 方式1:主动抛出Error throw new Error('test'); // 方式2:返回rejected状态的Promise return Promise.reject(new Error('test'));
内容的提问来源于stack exchange,提问作者Gautham Muralidharan
相关产品推荐
相关产品推荐

