首页 文章

等待Promise.reject或抛出错误来拯救?

提问于
浏览
1

我正在重构我的承诺,将代码链接到异步/等待样式 . 这样做的原因之一是我想要一个catch块来处理所有错误情况(如Understanding promise rejection in node.js所述)

我的问题是,当我遇到同步错误时,我应该拨打 await Promise.rejectthrow error 来拯救这个过程吗?我知道无论哪种方式都有效,但我更喜欢 throw error . 我已经知道我得到了无效的结果我为什么要等待?使用throw来立即终止控制流似乎是一个更好的选择 .

我不是在谈论诺言链(我的问题的全部要点),所以我不认为线程JavaScript Promises - reject vs. throw回答了我的问题 .

我读了文章Error Handling in Node.js我不认为它也给出了答案 . 但确实如此

给定的函数应该同步(使用throw)或异步(使用回调或事件 Launcher )传递操作错误,但不能同时传递两者 . ...一般来说,使用throw并期望调用者使用try / catch是非常罕见的......

我的异步函数可能会返回Promise.reject . 因此,我担心引入两种方式来提供错误,因为该文章反对 .

try {
   let result = await aysncFunc().
   if (!isResultValid(result)) { //isResultValid() is sync function 
      await Promise.reject('invalid result')
      //or throw 'invalid result'
   }
   ... //further processing
}
catch (error) {
  ...
}

1 回答

  • 1

    在promise控制流程中使用 throw 在语义上是正确的,这通常是摆脱承诺链的最佳方式 .

    根据编码风格, await Promise.reject(...) 可用于区分实际错误和预期拒绝 . 带有字符串原因的拒绝承诺有效,但 throw 'invalid result' 被认为是可以使用linter rules解决的样式问题,因为使用 Error 实例作为例外是常规的 .

    使用 instanceof Error 检测到's important is because string exceptions can'并且没有 message 属性的原因,一致的错误记录为 console.warn(error.message) 将导致模糊的 undefined 条目 .

    // ok
    class Success extends Error {}
    try {
      throw new Success('just a friendly notification');
    } catch (err) {
      if (!(err instanceof Success)) {
        console.warn(err.message);
        throw err;
      }
    }
    
    // more or less
    const SUCCESS = 'just a friendly notification';
    try {
      await Promise.reject(SUCCESS);
    } catch (err) {
      if (err !== SUCCESS)) {
        console.warn(err.message);
        throw err;
      }
    }
    
    // not ok
    try {
      throw 'exception';
    } catch (err) {
      if (typeof err === 'string') {
        console.warn(err);
      } else {
        console.warn(err.message);
      }
    
      throw err;
    }
    

    由于 invalid result 实际上是一个错误,因此将其设为一个是合理的:

    throw new TypeError('invalid result');
    

    我不是在谈论诺言链(我的问题的全部意义),所以我不认为线程JavaScript承诺 - 拒绝与抛出回答了我的问题 .

    async 函数是承诺链的语法糖,因此适用于承诺的所有点也适用于 async .

    可能存在抛出错误与拒绝承诺不同的情况,但它们特定于其他承诺实现,如AngularJS $q ,并且不会影响ES6承诺 . Promise 构造函数中的同步错误导致异常,这也不适用于 async .

相关问题