NodeJS 如何重构此函数以将其认知复杂度从16降低到允许的15?

7kqas0il  于 2023-05-06  发布在  Node.js
关注(0)|答案(3)|浏览(166)

当我添加此检查时:card.targetUrl!==“/test”
我得到了这个错误,我不能提交,我如何降低这个复杂性?

const link = useMemo(() => {
    if (!card?.targetUrl || card.targetUrl === "/test") {
      return "/account";
    } else {
      return card.targetUrl;
    }
  }, [card]);

当代码看起来像这样时,不会出现此错误:

const link = useMemo(() => {
    if (card?.targetUrl) {
      return card.targetUrl;
    } else {
      return "/account";
    }
  }, [card]);
v09wglhw

v09wglhw1#

只需删除useMemo。它需要的CPU时间比它内部的计算更多。

const link = !card || card.targetUrl === "/test" ? "/account" : card.targetUrl

使用useMemo,每次渲染你都必须创建一个函数,获取以前存储的依赖项,循环它,即使没有任何变化,你也已经花费了十倍于简单字符串比较的CPU时间。如果换了牌,那么...uhh.执行函数,将返回值存储在某处,替换依赖项..然后把钩子存储到钩子执行链中。我相信更多的开销在这里。

cfh9epnr

cfh9epnr2#

当线性控制流出现中断时,认知复杂性会增加。ifelse块和早期返回可能会增加它。你可以通过使用默认值初始化一个变量来删除一个内部块和早期返回,就像这样:

const link = useMemo(() => {
    let url = card?.targetUrl;
    if (!url || url === "/test") {
       url = "/account";
    }
    return url;
  }, [card]);
zf9nrax1

zf9nrax13#

认知复杂度可以是defined作为“* 一个代码单元直观理解的难度的度量 *”。
对我来说,你的代码现在的意图不是很明显,因为我需要在脑海中计算空检查,否定,or和右边的相等。当我们在写的时候,看起来并不多,但是其他人(甚至你以后)可能会发现它很难阅读,因此认知复杂性得分很高。
我给你一些建议,让你更容易理解:
1.将每个条件放在单独的if子句中:

const link = useMemo(() => {
  if (card?.targetUrl == null) {
    return "/account";
  }
  if (card.targetUrl === "/test") {
    return "/account";
  }
  return card.targetUrl;
}, [card]);

有些人可能会犹豫是否要重复相同的返回值(还记得DRY吗?),但是让你的代码更容易阅读,更容易修改,这是值得的。例如,也许你以后想删除card.targetUrl === "/test"条件,在上面的示例代码中,这很容易,因为它们是分开的。
1.不要使用else关键字。
由于您的代码正在执行提前返回,因此不需要else子句。这个建议来自Object Calisthenics,看看吧。
1.如果你不想重复返回,还有另一种方法可以让代码更具可读性,方法是将条件提取到一个新函数中,并给它一个描述性的名称(请原谅我生 rust 的Javascript):

const link = useMemo(() => {
  if (shouldUseDefaultUrl(card)) {
    return "/account";
  }
  return card.targetUrl;
}, [card]);

function shouldUseDefaultUrl(card) {
  if (card?.targetUrl == null) {
    return true;
  }
  if (card.targetUrl === "/test") {
    return true;
  }
  return false;
}

相关问题