ruxuan1306

ruxuan1306

V2EX 第 369495 号会员,加入于 2018-12-11 00:52:37 +08:00
今日活跃度排名 15115
根据 ruxuan1306 的设置,主题列表被隐藏
二手交易 相关的信息,包括已关闭的交易,不会被隐藏
ruxuan1306 最近回复了
53 天前
回复了 jkfadsljlasdgs 创建的主题 OpenAI Copliot 帮你解决了什么问题?
Copilot 擅长将非结构数据转换为结构数据。

直接注释接口文档里的描述,稍微起个头就能快速定义 TypeScript 类型和枚举。
60 天前
回复了 tianshunovel2 创建的主题 云计算 非得用微服务吗?
没必要,微服务的架构本质来自组织架构。
纠结就买 iPhone ,因为安卓不好用时一定会后悔没买 iPhone ,iPhone 不好用时会自适应。
粘出来格式不好看,原文来自: https://zexi.notion.site/b9f941b097054bb1a28de1de61535adf
我看之前楼层都在情绪输出,我来说说我的思考吧。



两个前提:
1. 老板只在意业务功能是否实现,没人在意前后端之间的接口质量;
2. 督促后端交付高质量接口的沟通成本远大于前端写几行 map 的开发成本;

故结论,前端兼容。



问题是,对于前端的某一字段,不同的后端提交、响应不同,甚至值的类型也不同。
导致在写 TypeScript 时,就要定义大量 TS 类型,还很难起名。
但仔细想想我们真的需要这些“一次性”类型吗?



看个例子,假设我们有两个接口:

```JavaScript
// id 查 user
const res = fetch.get('/user', { id: 1 })
console.log(res.body) // { id: 1, name: 'alice' }

// id 改 user 名
const res = fetch.post('/user', { user_id: '1', new_username: '' })
console.log(res.body) // { code: 1 }
```

很难受吧,查和改的字段居然不一致。
那我用户 ID 究竟叫 id 还是 user_id ?类型究竟是 number 还是 string ?

很简单,按前端方便来:

```
type User = {
userId: string,
username: string
}

<div>
<div>用户 ID:{{userId}}</div>
<div>用户名:<input type="text" value="{{username}}" /></div>
</div>
```



???



因为 JavaScript 里常用驼峰命名,userId 通常也只是展示,不会涉及什么数值运算,绑定 input 之类也比较方便…

噢,哈哈,你肯定早就知道这些,我知道你是在疑惑,接口怎么办?

别急。



我们知道,TypeScript 类型系统很好很强,除非 any 泛滥。
要想抑制 any 渗入 TS ,就要观察 any 从哪产生:

什么函数返回 any ?

- JSON.parse()
- fetch()
- ...

喔,外部数据流入 TS 时,就是 any ,有才有德的我知道,此时我应该立刻手动为标记类型:

```JavaScript
// 接口响应类型
type GetUser = { id: number, name: string }

// 前端易用类型
type User = { userId: string, username: string }

function fetchUser(userId: string) {
// 外部数据
const res = fetch.get('/user', { id: Number(userId) })
console.log(res.body) // { id: 1, name: 'alice' }

// 标记类型 any -> GetUser
const data: GetUser = res.body

// 转为前端易用的格式
const user: User = {
userId: String(data.id ?? ''),
username: data.name
}
return user
}
```

很好很完美,我们成功封装了一个接口请求函数,它能通过 string 的 userId ,查到 User 数据,以前端想要的格式。

但多看一眼,我们真的有必要定义 GetUser 吗?

简化下可以吗:

```JavaScript
type User = { userId: string, username: string }

function fetchUser(userId: string): User {
const res = fetch.get('/user', { id: Number(userId) })
return {
userId: String(res.body.id ?? ''),
username: res.body.name
}
}
```

噢,虽然 res.body 是 any ,虽然按照 TypeScript 最佳实践我应该马上声明它的类型,但事实上,完全可以将这个明晰 any 的过程延迟到数据转换一并进行。

这样一切就变得简单多了,只要我守好数据流入和流出的关口,那无论多离谱的后端,我都不需撕逼,分钟对接:

```JavaScript
function updateUser(userId: string, username: string): boolean {
const res = fetch.post('/user', {
user_id: Number(userId),
new_username: username
})
return res.code === 1
}
```


于是作为前端:
在开发阶段,我以最舒适的姿势定义 State 的数据结构、绑定 UI 组件。
在联调阶段,我直接对着浏览器抓包的响应体,实现关口函数内的转换。
完全摆脱各接口字段定义不一致、实际响应和接口文档不符、string 和 number 类型没对上之类来回沟通筋疲力尽的鸡零狗碎。



再温故一遍:
1. 老板只在意业务功能是否实现,没人在意前后端之间的接口质量;
2. 督促后端交付高质量接口的沟通成本远大于前端写几行 map 的开发成本;
109 天前
回复了 victorc 创建的主题 OpenAI GPT 是程序员卖给资本家的绞索
在公司开发流程中,开各种评审会议、写各种留痕文档、读历史屎山、和测试来回拉锯的工时最多,编码的占比非常之小。
哦不好意思没注意,原来是在对比计算机运行的效率,不是人算出结果的效率
Excel-数据分析-回归

@yfugibr 自动扩容是在 append 时原容量不够才发生的,new 时候给定大小,然后直接用下标设置就不会触发扩容。
110 天前
回复了 tasselyue 创建的主题 职场话题 即将毕业该怎么办? 好迷茫
想太远了,这才大三上,考虑考研考公就业那都是明天春天后的事。

---

**“我也意识到了,但我不知道该怎么改变。”**

先从每天运动开始。

人在成年后,只有健身是一分努力一分收获。

健身的反馈周期也比较合适,叠上新手福利期,最多一两周就能看到配速变快了、心率变低了、肌肉变强了,这些都是结结实实的正反馈。

**你必须首先做成一件事,才能获得自己有能力做成事的信心。**

躺在宿舍床上畏畏缩缩瞻前顾后?

起来。
训练。
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   952 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 11ms · UTC 21:22 · PVG 05:22 · LAX 13:22 · JFK 16:22
Developed with CodeLauncher
♥ Do have faith in what you're doing.