使用Facebook的不变vs如果扔

时间:2016-08-20 14:22:46

标签: javascript error-handling invariants

我一直在关注各种Node.js项目'来源,我注意到有些人使用invariant。根据我的理解,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');
   }
}

2 个答案:

答案 0 :(得分:21)

有几个原因:

  • 当您想要堆叠它们时,它更容易阅读。如果你有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");
}

与通常的投掷方法比较:

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");
}
  • 在发布版本中可以轻松消除它。

    通常您希望在开发/测试中检查前提条件,但由于它们的速度有多慢,因此不希望它们在发布中。 如果你有这样的invariant函数,你可以使用像babel(或其他)这样的工具从生产版本中删除这些调用 (这有点像D的做法)。

答案 1 :(得分:2)

zertosh/invariant允许添加code guards

如自述文件所述,这是提供开发中描述性错误但提供生产中通用错误的方法

但是,它是某些内部facebook系统的复制,并且imo记录得很差,并且没有维护。可怕的是4.4M使用的是:thinking:

  • 所有内容都不会被拆开
  • 如果您没有用于以某种方式删除生产中消息的构建工具,您仍然会遇到原始错误
  • 节点中的用法用于ssr / react本机,或者在“我们的行数更少”之外没有用处
  • 它使用error.framesToPop,这也是Facebook上的东西

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

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

cond || throw x
cond ?? throw x

那样,如果cond在浏览器中包含虚假的var env,则无论如何都不会评估错误并清除错误