【问题标题】:Handling Js promise rejection处理 Js 承诺拒绝
【发布时间】:2017-04-14 07:15:50
【问题描述】:

你如何处理超出承诺的错误(例如下面的“新错误”)?

function testError() {
    throw new Error("new error") // how to handle this?
    var p123 = new Promise(function(resolve, reject) {
         resolve(123)
    });
    return p123
};

testError().catch(err => {
        return err;  // code doesn't come here
    })
    .then(ok => {
        console.log(ok)
    });

【问题讨论】:

标签: javascript promise es6-promise request-promise


【解决方案1】:

如果您不确定函数是否会同步抛出(或返回值),您可以使用.then() 调用它。这将包装它,以便无论结果如何产生都将得到一致的处理:

function testError() {
  throw new Error("new error") // how to handle this?
  var p123 = new Promise(function(resolve, reject) {
    resolve(123)
  });
  return p123
};

Promise.resolve()
  .then(testError)
  .catch(err => {
    console.error(err);
    return err; 
  })
  .then(ok => {
    console.log(ok.message)
  });

【讨论】:

  • 请注意,从 ES2018 开始,您可以使用 .finally() 而不是第二个 .then() 调用,它做同样的事情,但意图更清楚(它总是会被调用,即使承诺错误已经结束)。
【解决方案2】:

由于错误不涉及异步代码,因此常规 try-catch 在这里应该可以正常工作:

try {
  testError().catch(err => {
    return err;  // code doesn't come here
  })
  .then(ok => {
     console.log(ok)
  });
}
catch(e) {
   // 
}

请注意,当async-await 模式最终成为解决承诺的原生方式时,try-catch 也将成为处理错误的原生方式:

try {
    var ok = await testError();
    console.log(ok)
}
catch(e) {
    console.log('e:' +e);
}

可以很容易地验证,这个可以正确处理同步和异步错误,并且比then-catch 干净得多。

【讨论】:

  • 这会起作用,但它会使逻辑流程变得非常混乱,并破坏了 Promise 提供的一致性。
  • @JLRishe:在我的回答中解决了这个问题 - try-catch 提供了最终的一致性。
  • async/await 可用时有效,但不可用时无效。
【解决方案3】:

如果可以的话,像这样重写你的 testError 函数

function testError () {
  return new Promise(function (resolve, reject) {
     throw new Error('new error')
     resolve(123)
  })
}

testError().then(ok => console.log(ok),
                 err => console.error(err.message))
  1. 运行一次,看到它在console.error 中抛出错误
  2. 注释掉throw 行以查看promise 成功解决

【讨论】:

    【解决方案4】:

    由于错误是在 Promise 之外抛出的,因此您无法使用 Promise catch 语句捕获它。

    您可以改用 try/catch 来捕获错误。

    function testError() {
        throw new Error("new error") // how to handle this?
        var p123 = new Promise(function(resolve, reject) {
             resolve(123)
        });
        return p123
    };
    
    try {
      testError().then(ok => {
        console.log(ok)
      });
    } catch (err) {
      console.log(err.message);
    }
    

    【讨论】:

      【解决方案5】:

      你重写它,因为让调用者同时检查异常和拒绝是一种反模式:

      function testError() {
        return Promise.resolve().then(() => {
          throw new Error("new error"); // rejects returned promise
          return new Promise(function(resolve) {
            resolve(123);
          });
        });
      }
      
      testError().catch(err => console.log("Caught " + err));

      这对于async 函数是隐含的;他们总是返回一个承诺:

      async function testError() {
        throw new Error("new error"); // rejects implicit promise
        return await new Promise(function(resolve) {
          resolve(123);
        });
      }
      
      testError().catch(err => console.log("Caught " + err));

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-31
        • 2023-03-17
        • 2018-04-01
        • 2021-09-19
        • 1970-01-01
        相关资源
        最近更新 更多