【问题标题】:correct way to handle errors inside a Promise处理 Promise 中错误的正确方法
【发布时间】:2019-05-17 03:36:15
【问题描述】:

目前,我正在尝试决定在处理 Promise 中的错误时应该使用什么模式。例如,我有下面的代码

promiseFunc()
.then(result => {

    console.info(`.THEN:: ${result}`)
})
.catch(error => {

    console.info(`.CATCH:: ${error}`)
})

function promiseFunc() {

    return new Promise((resolve, reject) => {

        setTimeout(() => {

            throw Error("setTimeout's callback error")
            resolve('resolution')           
        }, 1000)
    })
}

如果其中的一个函数(在我的例子中为 setTimeout())抛出一个错误,应该使用什么方法来拒绝 Promise。换句话说,我需要拒绝而不是错误,但我想到的唯一想法是添加一个 try/catch 块并从 catch 中拒绝 Promise。

【问题讨论】:

  • 似乎是正确的方法。
  • 与不使用 Promise 并需要捕获错误的情况没有什么不同。所以try/catch 是合适的方法
  • @charlietfl 除非您使用 async/await 进行编程,否则您不需要 try/catch 与 promises
  • @Bergi 的观点是,如果在显示的 setTimeout 内发生错误,则需要捕获它
  • @charlietfl 重点是一开始就不应该允许这种情况发生:-)

标签: javascript node.js promise


【解决方案1】:

您在异步函数中抛出错误,而不是拒绝承诺。

throw Error("") 更改为reject("")

promiseFunc()
  .then(result => {
    console.info(`.THEN:: ${result}`)
  })
  .catch(error => {
    console.info(`.CATCH:: ${error}`)
  })

function promiseFunc() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("setTimeout's callback error")
      resolve('resolution')
    }, 1000)
  })
}

或者添加一条try-catch语句,并在catch块中拒绝

setTimeout(() => {
  try {
    throw new Error("setTimeout's callback error")
  } catch(error) {
    reject(error)
  }
  resolve('resolution')
}, 1000)

【讨论】:

  • 您好,感谢您的回复。这个案例只是真实案例的简化版本 - 如果我有一个 really 可以抛出错误而不是我的 throw Error("setTimeout's callback error") 的函数 - 我应该如何处理那?附言刚刚看到您更新的回复 - 所以,我认为我必须在我的情况下使用 try/catch
【解决方案2】:

Resolve、Reject 和 Error 是三个不同的东西,当您需要解决和拒绝它时,您的代码需要处理这些情况。如果您想要的条件已满,则调用 resolve 方法,如果条件不能满,则调用 reject() 方法。

如果您的代码抛出任何错误或任何其他原因,链末尾的单个 catch() 块将被执行。

// doAsyncOperation1() returns a promise.
doAsyncOperation1()
.then(() => {
  // ...
  // doAnotherAsyncOperation() returns a promise
  // which will be inserted into the chain.
  return doAsyncOperation2();
})
.then((output) => {
  // output will be the value resolved by the
  // promise which was returned from doAsyncOperation2()
  // ...
  return doAsyncOperation3();
})
.catch((err) => {
  // Handle any error that occurred in any of the previous
  // promises in the chain.
});

【讨论】:

    【解决方案3】:

    如果其中的函数(在我的例子中为 setTimeout())抛出错误,应该使用什么方法来拒绝 Promise

    异步回调绝不能抛出异常。您尝试承诺的函数(setTimeout)要么引发同步异常(new Promise 处理),要么调用回调。在回调中您必须调用resolvereject,并且这样做不会引发异常。

    如果你想在回调中做额外的事情(除了调用resolve/reject),可能会抛出异常的事情:不要

    new Promise 应该只包装您想要承诺的直接函数,不要包装其他任何东西。在链接到 promise 的 then 回调中做更多的事情 - then 将在其回调中处理异常就好了:

    function promiseFunc() {
      return new Promise(resolve => {
        setTimeout(resolve, 1000);
    //             ^^^^^^^ nothing can go wrong in here
      }).then(() => {
        throw "setTimeout's callback error";
    //  ^^^^^ here, it will lead to a rejection
        return "resolution";
      });
    }
    

    【讨论】:

    • 太棒了,我知道我的理解是错误的。感谢您的提示!
    • 您为我澄清了一些事情。非常感谢!
    猜你喜欢
    • 2019-10-20
    • 2017-08-21
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 2019-05-25
    • 2017-08-09
    • 2019-02-01
    • 1970-01-01
    相关资源
    最近更新 更多