等待 Promise.reject 或抛出错误来摆脱困境?

Qiu*_*ang 6 javascript node.js promise async-await

我正在将我的承诺链接代码重构为异步/等待风格。这样做的原因之一是我想要一个 catch 块来处理所有错误情况(如此处所述Understanding Promise Rejection in Node.js

我的问题是,当我遇到同步错误时,我应该致电await Promise.reject还是throw error退出该过程?我知道这两种方式都可以,但我更喜欢throw error。我已经知道我得到的结果无效,为什么还要等待?使用 throw 立即终止控制流似乎是更好的选择。

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

我读过《Node.js 中的错误处理》一文,我认为它也没有给出答案。但它确实说了

给定的函数应该同步(使用 throw)或异步(使用回调或事件发射器)传递操作错误,但不能同时传递。...一般来说,使用 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) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

Est*_*ask 5

在 Promise 控制流中使用在语义上是正确的throw,这通常是摆脱 Promise 链的更好方法。

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

它之所以重要,是因为字符串异常无法被检测到,instanceof Error并且没有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;
}
Run Code Online (Sandbox Code Playgroud)

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

  throw new TypeError('invalid result');
Run Code Online (Sandbox Code Playgroud)

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

async函数是 Promise 链的语法糖,因此适用于 Promise 的所有要点async也都适用。

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