CodeReview常见的几个问题梳理解决示例

写在前面

文章的主要作用是帮助自己进行思考和总结,比如我们可能都遭遇过功能上线后出现了一些不可预知的bug,我们对这些bug进行处理,完善之后,项目负责人可能会叫上这个功能的主要几个开发人员做一次复盘会议,大家一起讨论出现问题的原因,然后定制对应的方案,防止类似的情况再次出现。

写文章的道理其实跟开复盘会议一样,通过思考和总结,我们可以将自己改变的更好。学习可以改变自己,而我们也正是为了改变而学习,写文章也是一种学习的方式。

当然,由于文笔及文采的限制,写的内容可能无法满足所有人的需求,但是,这些内容中,只要能够讲清楚一件事,讲清楚哪怕只有一个知识点,这件事或者这个知识点哪怕只有一个人认同,那么,写这些东西就是有意义的。

Review的功能模块

这次CodeReview涉及的功能是数据的推理训练模块,具体的需求是开发人员在录入数据时,有两种格式:yaml和json,有些人对yaml的数据格式不太清楚,所以需要有一个地方能够支持yaml语法的配置,同时支持yaml和json之前的互相转化,即:输入yaml后,突然发现其实需要的是json,那么可以直接转成json格式传给后端,反之亦然。

yaml和json之前相互转化的功能,npm上有相应的包,有兴趣的可以了解一下,这里就不再叙述了。

Reviewd的问题(收获)

  • 真需求 VS 伪需求

直属领导上来就提了一个致命的问题:这个功能是谁在用?真的有必要做这个功能吗?

作为开发人员,假如我们不熟悉yaml的语法格式,我们可以快速的去学习一下,那么就没有必要去浪费人力和时间去开发这个功能,把时间用来开发更重要的功能岂不是更好?

当然,这里也不是说这个功能不好,这里反映出的问题是:在开发一个功能前,我们到底有没有理解相应的需求?这个需求是个真需求,还是一个一个伪需求?。

这个问题在开发前是要确认清楚的。

  • 数据格式

当某个功能后期可能会进行扩展时,比如一个用于枚举的列表,后端返回的数据通常是一个数组。

对于这种可扩展的数据格式,我们需要而且必须和后端进行对齐,而且前端必须做相应的判空处理,永远不要相信后端返回的数据都是靠的。

比如下面两种格式,后端有可能会告诉你,它们都表示空数组。

var a = []
var b = [{name:''}]

后端有可能告诉你,啊,我这个b只会有一条数据,当name是空字符串的时候就表示这b没数据。

但是,a和b从根本上就代表了两种不同的含义。

所以,有歧义的数据格式一定要跟后端对齐,同时前端一定要做相应的防御性措施,该判空的判空。

  • 还是需要注意ts的类型定义

函数必须要有自己的返回值类型,函数参数也必须有相应的参数类型。凡是ts无法进行推断的地方,ts默认会推断为any类型,那么我们使用ts进行开发的意义又在哪里呢?

  • 异步函数的定义

通常在请求接口的时候我们会使用函数的异步标识async来定义异步函数。但是有时候可能写习惯了,在不需要做异步处理的地方也定义了异步函数,比如:

const print = async () => {
 console.log('print')
}

这时候就可能会出现意想不到的问题。

  • 该有注释的地方一定要有注释

定义的变量有歧义的,有一定的业务含义的地方,注释一定要清楚明了,比如:

if(dataDetail.target === 'pc'){
 // do something
}

pc如果有非常具体的业务含义,那么它表示的是personal computer 还是process center,或者是其他含义呢?

如果对有具体业务含义的变量定义的过于简单,且还有没相应的注释,那么不经意之间我们就给自己和其他同事挖了一个坑。

  • 运算符的使用

在用三元运算进行判断时,我们通常这样写:

let hasGold = detail.target ===''?false:true

这个判断我们可以用!!运算符进行优化:

let hasGold = !!detail.target

当然,还有很多其他的运算符,比如?.、??。双问号是null判断运算符,作用和||双竖线是一样的。

const headerText = response.settings.headerText || 'Hello, world!';
const headerText = response.settings.headerText ?? 'Hello, world!';

左侧为null 或者undefined时,右侧就会生效。

  • 代码外部注意try/catch的处理,防止有其他的异常情况

我们通常在写代码的时候,尤其是写页面交互相关的事件时,一般不怎么考虑使用try-catch做处理。

但是,页面上触发事件,用户手动触发的交互,我们有必要做一些防御性的措施,加入try-catch的处理,防止意想不到的问题出现。

try-catch的使用,个人理解的主要时用来防止一些外部的错误,比如:

try {
 console.log(a)
} catch (error) {
 console.error(error);
 // VM654:4 ReferenceError: a is not defined
 // at <anonymous>:2:15
}

有时候我们在定义变量或者函数的时候,可能会出现一些意想不到的问题,try-catch会提前将这些问题抛出来,避免产生更复杂的问题。

外部问题,可以理解为try{}花括号之外的问题。

最后

虽然这次CodeReview涉及的功能非常简单,其中暴露出来的问题依然值得我们去仔细思考一下。

尽管我们从事开发工作已经很有经验了,依然有很多地方值得去思考、去提升。

作者:前端那些年

%s 个评论

要回复文章请先登录注册