Promise.resolve()链式调用输出异常原因探究
为什么示例1的Promise链输出res1而不是res3?
这是个非常关键的Promise知识点,核心在于**.then()方法必须接收函数作为回调参数**,如果传入非函数值(比如直接传一个已resolved的Promise),会触发「值穿透」行为,直接把上一步的结果原封不动传递下去。
拆解示例1的执行逻辑
先看你的示例1代码:
Promise.resolve('res1') .then(Promise.resolve('res2')) .then(Promise.resolve('res3')) .then(function (result) { console.log(result); });
这里的问题出在.then(Promise.resolve('res2'))和.then(Promise.resolve('res3')):
.then()的第一个参数要求是当Promise兑现时执行的回调函数,但你传入的是一个已经resolved的Promise对象,不是函数。- 根据Promise规范,当
onFulfilled参数不是函数时,会被替换成一个默认的「恒等函数」:value => value,也就是直接把上一步Promise的结果原封不动返回。
所以示例1的执行流程等价于:
Promise.resolve('res1') .then(value => value) // 等价于传Promise.resolve('res2') .then(value => value) // 等价于传Promise.resolve('res3') .then(function (result) { console.log(result); });
每一步都只是把'res1'传递下去,最后自然输出res1。
示例2符合预期的原因
再看示例2的代码:
Promise.resolve('res1') .then(function (result1) { console.log(result1); return Promise.resolve('res2') }) .then(function (result2) { console.log(result2); return Promise.resolve('res3') }) .then(function (result) { console.log(result); });
这里每个.then()都传入了真正的回调函数:
- 第一个then的函数接收'res1',打印后返回新的Promise(resolve为'res2'),
.then()会等待这个新Promise兑现,然后把'res2'传给下一个then。 - 第二个then的函数接收'res2',打印后返回resolve为'res3'的Promise,同理传递给下一个then。
- 最后一个then接收'res3'并打印,所以输出顺序是
res1 res2 res3。
总结关键规则
- 永远记住:
.then()的参数必须是函数,如果传非函数值(包括Promise对象),就会触发值穿透,直接传递上一步的结果。 - 如果想在then里返回新的Promise并让后续then接收其结果,一定要把返回Promise的逻辑放在函数内部,而不是直接把Promise传给then。
内容的提问来源于stack exchange,提问作者Jalak Patoliya
相关产品推荐
相关产品推荐

