You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 18:36:03