一直以来, 前端工程代码中有着大量的对于接口返回字段值为null的处
理. 在实际项目中, 接口字段返回null的情况也是普遍状况.
已然变成了一种合理形式.
这有什么问题呢?
- 不符合接口字段的类型约定
由于前后端配合是基于接口文档的, 每个字段都有明确的类型, 如果接口的某个字段约定是Array, 但返回的值为null, 实际上对于前端, 是类型错误, null的类型是Object.
由于基于接口文档我们预期接口返回的是Array类型,
所以, 本应放心的使用数组的方法,
但是, 如果此时接口返回了null,
实际上是返回了Object类型,
等于违背了接口文档的约定.
phoneNumbers.sort()
- 额外的防御性代码, 需要手工保障
由于任何值都可能是null, 在使用是都需要防御,
随着工程发展,这种状况会很泛滥
ps:
事实上, 对于泛前端来说, 也需要保证代码健壮性.
但检查的规则, 是基于接口约定的.如果不符合接口定义会统一弹出统一报错.而不是在业务逻辑中逐一防范.
// 如果phoneNumbers来自于接口, 且值是null , 直接就会报错
const phoneNumbers: number[] = []
// 此时, 由于null的类型是object并不是array,
// 所以sort的方法就会在报错.
console.log(phoneNumbers.sort())
// 这时只能先判断再使用
if (Array.isArray(phoneNumbers) ) {
phoneNumbers.sort()
}
// 换成不严谨的简单粗暴的判断方式
phoneNumbers && phoneNumbers.sort()
那么为什么后端要返回null呢?
- 语言特性
java语言: 认为返回默认值会占用内存, 比如空数组也需要占用内存, 空字符串也要占用内存.
- 开发成本
对于一些后端工程, 想要加默认值, 成本非常高, 需要逐个去加 (容我质疑一下, 难道就没有便捷的)
前端手动书写防御性代码会带来什么问题?
1.难以避免的疏忽
所有依靠手动保障的工作, 本质上都是在对赌一个词: “认真”, 显然, 智者千虑必有一失, 谁都不能确保没有疏忽, 如果可能使用工具代替手工才是出路.
2.难以测试, 成为线上质量的隐患
这种防御性代码带来的问题,本质上是由数据不符合规范导致的, 往往开发测试阶段, 数据都是理想的, 甚至线上回归测试时也没问题, 但经常有一些线上故障是这样的
1. 前端功能发生致命错误,导致交互无法继续
由于接口返回的数据没有遵守按照协议, 导致的前端错误.
2. 没有报错, 但流程异常
举个例子: 某个枚举值, 对应着前端的单选框,
例如 是/否 , 起初约定0: 是, 1: 否 , 但由于某种原因数据变成了1: 是, 2: 否 ,
从交互上就出现了问题且一般不会报错.
随着交互继续进行, 问题将难以定位,
在这过程中流失的用户订单将会与定位、解决问题的时间成正比, 实为不能承受之重.
现在, 我们面临的问题是什么?
- 如何保证泛前端代码在数据交换时的健壮性.
- 前端工程的可维护性, 是否重要?
- 线上质量与性能到底哪个重要?
以下的认知, 期待我们能达成共识:
前后端通过接口文档(协议约定)进行数据交换合作, 例如: 每一个字段“是否必须”, 字段类型, 枚举, 都有唯一性的明确约定. 双方都须遵守数据交换协议, 才能保证线上质量.
解决方案当然也是有的, 请关注下一期, :
《如何不增加泛前端维护成本又能增强数据交换过程中泛前端代码的健壮性》 ?
推荐给后端同学的参考阅读:
不要再返回Null了
https://juejin.im/post/6844903683436576776