Promise中return new Error与throw的差异解析
核心原因
Promise的then/catch回调中,只有两种情况会触发后续的catch回调:
- 主动抛出异常(throw)
- 返回一个状态为rejected的Promise
而return new Error('test')只是返回了一个普通的Error实例对象,属于Promise的正常resolved结果,因此会被传递给下一个then的回调,而非进入catch。
具体区别解析
throw 触发reject流程
当你在then回调中throw一个值时,当前Promise的状态会立即变为rejected,Promise链会跳过后续的then,直接寻找最近的catch来处理这个异常。比如你代码中:.then(function(data) { if (data !== 'victory') { throw 'Defeat'; } return job(true); })这里
throw 'Defeat'让Promise状态变为rejected,所以直接进入了后面的catch,打印出Defeat。return Error实例属于正常返回
Error本质上是一个普通的JavaScript对象,和return {msg: 'test'}没有本质区别。当你在then中返回它时,Promise会将这个对象作为resolved的值,传递给下一个then的回调参数。比如你代码的最后一段:.then(function(data) { console.log(data); return new Error('test'); }) .then(function(data) { console.log('Success:', data.message); })这里
new Error('test')被当作上一个then的成功结果,所以下一个then接收到这个Error实例,打印出Success: test。
触发catch的正确方式
如果想让Error触发catch,可以用两种方式:
- 抛出Error:
.then(function(data) { console.log(data); throw new Error('test'); }) - 返回rejected的Promise:
.then(function(data) { console.log(data); return Promise.reject(new Error('test')); })
结合你的运行结果验证
你的代码运行结果最后一行是"Success:" "test",正好对应上述逻辑:return new Error('test')作为resolved值进入下一个then,回调中读取data.message得到test并打印。
内容的提问来源于stack exchange,提问作者Lam My Ky - Kailey

