JS Promise实操结果不符合预期,全部请求报错时第二个then却进入成功回调
问题原因
这是Promise的回调返回值规则导致的,核心逻辑如下:
- Promise的
then方法无论触发的是成功回调还是失败回调,只要回调函数没有主动抛出错误,也没有返回一个rejected状态的Promise,那么这个then返回的新Promise默认就是fulfilled(成功)状态,会走到下一个then的成功回调中。 - 你的第一个
then的失败回调里仅打印了第一次失败的日志,没有做任何其他处理:- 没有返回
sendTwo(),所以第二个请求甚至都没有被触发 - 没有抛出错误/返回rejected的Promise,导致第一个
then返回的Promise状态为成功,直接触发第二个then的成功回调,所以才会打印出「Succeeded the second time」,这和第二个请求本身的返回结果没有任何关系,因为第二个请求根本没有执行。
- 没有返回
修复方案
如果希望错误可以向下传递触发后续的失败回调,可以采用下面两种方式:
方案1:失败回调中抛出错误/返回rejected的Promise
p1 .then(function(data) { console.log("Succeeded for the first time"); return sendTwo(); }, function(data) { console.log("Failed for the first time") // 抛出错误,让后续的then触发失败回调 throw new Error('first request failed') // 或者返回rejected的Promise: return Promise.reject(data) }) .then(function(data) { console.log("Succeeded the second time"); return sendThree(); }, function(data) { console.log("Failed the second time") throw new Error('second request failed') }) .then(function(data) { console.log("Succeeded the third time"); }, function(data) { console.log("Failed for the third time") })
方案2:全局用catch统一捕获错误(更推荐)
去掉每个then的第二个失败回调,统一在链式调用末尾加catch捕获整个链的错误,符合Promise的错误处理最佳实践:
p1 .then(function(data) { console.log("Succeeded for the first time"); return sendTwo(); }) .then(function(data) { console.log("Succeeded the second time"); return sendThree(); }) .then(function(data) { console.log("Succeeded the third time"); }) .catch(function(err) { // 任何一步出错都会走到这里 console.log('请求出错:', err) })
如果需要每一步的错误都单独处理,只需要在对应步骤的失败回调里处理完后继续抛出错误即可。
内容的提问来源于stack exchange,提问作者lcrazyl
相关产品推荐
相关产品推荐

