使用Facebook的不变量vs if throw

rod*_*ira 18 javascript error-handling invariants

我一直在关注各种Node.js项目的来源,我注意到有些人使用了不变量.根据我的理解,这invariant是一个工具,可以让您在代码中放置断言,并根据需要引发错误.

题:

什么时候你喜欢用invariant传统方式使用vs抛出错误?

// Using invariant
function doSomething(a, b) {
   invariant(a > b, 'A should be greater than B');
}

// If throw
function doSomething(a, b) {
   if(a <= b) {
      throw new Error('A should be greater than B');
   }
}
Run Code Online (Sandbox Code Playgroud)

Ven*_*Ven 26

有几个原因:

  • 当你想要堆叠它们时,它更容易阅读.如果您有3个先决条件进行验证,您总能看到invariant(x ...,并且很容易看到正在检查的内容:

function f(xs, x) {
    // all the invariants are lined up, one after another
    invariant(xs.type == x.type, "adding an element with the same type");
    invariant(xs.length != LIST_MAX_SIZE, "the list isn't full");
    invariant(fitting(x), "x is fitting right in the list");
}
Run Code Online (Sandbox Code Playgroud)

与通常的抛出方法相比:

function f(xs, x) {
    if (xs.type != x.type)
       throw new Error("adding an element with the same type");
    if (xs.length == LIST_MAX_SIZE)
       throw new Error("the list isn't full");
    if (!fitting(x))
       throw new Error("x is fitting right in the list");
}
Run Code Online (Sandbox Code Playgroud)
  • 它使得在发布版本中消除它变得容易.

    通常你需要在dev/test中检查前提条件,但是由于它们的速度有多慢,所以不希望它们在发布中.如果你有这样的invariant功能,你可以使用像babel(或其他)这样的工具从生产版本中删除这些调用(这有点像D的做法).

  • 嗯,禁用prod中的断言会听起来不错。使用`if throw`方法很难做到这一点。 (2认同)

Sce*_*eat 5

zertosh/invariant允许添加代码防护

正如自述文件中所述,它是一种在开发中提供描述性错误但在生产中提供一般错误的方法

然而,它是一些 Facebook 内部系统的复制品,而且 imo 的记录非常糟糕,也没有维护。可怕的是 4.4M 使用 :thinking:

  • 没有任何东西会开箱即用
  • 如果您没有构建工具以某种方式删除生产中的消息,您仍然会遇到原始错误
  • Node 中的用法适用于 ssr/react 本机,或者在“我们的行数较少”之外无用
  • 它使用的error.framesToPop也是 facebook 的东西

请参阅: https: //github.com/zertosh/invariant/issues?q =is%3Aissue

注意:更好的方法是等待 es 提案throw inline并实际执行

cond || throw x
cond ?? throw x
Run Code Online (Sandbox Code Playgroud)

这样,如果 cond 在浏览器中包含 falsy var env,则无论如何都不会评估错误并删除该错误