最近在学函数式编程,总总不能体会它的好处,而且看了几个礼拜,还没有产出一行可以上生产的代码,所以想用最日常的过程式的代码,请教下各位大佬,看看如何优化
// import {message} from 'antd'
// import {fetchApi} from '@/api'
// import moment from 'moment'
// const [detail, setDetail] = React.useState()
const validator = async () => {
// do something
}
const getDetail = async (params) => {
await validator();
try{
const res = await fetchApi({name: 'name', ...params, id: 1})
if (res.code >= 200 && res.code < 400) {
const {list, obj} = res.data
const {date1, num1 = 1, num2, ...objRest} = obj
const formData = {
list: list?.map(item => {
const {p1, ...itemRest} = item
return {
...itemRest,
p2: p1
}
}),
obj: {
...objRest,
date1: date1 && moment(date1).format("YYYY-MM-DD"),
num1: Number(num1),
num2: Number(num2),
}
}
setDetail(formData)
} else {
throw Error(res.msg)
}
} catch (err) {
message.error(err?.message || '请求错误')
}
}
这个应该是前端最基础的接口处理了,基本上囊括了我会碰到的各种问题。我感觉能用 ramdajs 或者 lodash/fp 等函数库把这个函数用函数式编程优化了,基本上就 fp 通关了
1
vance123 2022-04-14 22:35:49 +08:00 via Android
问题应该不在过程式或是函数式。好的代码一次只做一件事,你这段代码一次做了 n 件事
|
2
chenliangngng OP @vance123 中间这个字段映射的部分呢
```javascript const {list, obj} = res.data; const {date1, num1 = 1, num2, ...objRest} = obj const formData = { list: list?.map(item => { const {p1, ...itemRest} = item return { ...itemRest, p2: p1 } }), obj: { ...objRest, date1: date1 && moment(date1).format("YYYY-MM-DD"), num1: Number(num1), num2: Number(num2), } } ``` |
3
GeruzoniAnsasu 2022-04-14 23:00:42 +08:00 4
函数式的精髓在于「符号演算」,本质上是一些公式代换,所以是在处理复杂对象关系和约束时才比较好用,并不是说函数式就比过程式更优雅,先走出误区。
再说实例。 你展示的一个 getdetail 的过程: 1. 调接口 2. 验证拉取结果 3. 对参数进行「变换」 这个描述本身就非常过程化,有明确的分段步骤,并不存在关系约束的语义,所以用函数式写本来也不适合。 当然也不是不可以,我们换个描述: 1. setdetail 接受「 raw 数据的变换结果」,最终将结果闭包展开,暂时先不管它内部什么样 2. 「 raw 变换结果」可以写为将「变换」应用到「 raw 」上 ← 函数化 3. 「 raw 数据」可以看做将「请求提取子(包含验证子)」应用在「数据源」上←函数化 4. 「数据源」是一个「输入请求类型然后重封装为响应类型的 monad 」←函数化 5. 「请求类型」 由 「请求类型变换子」应用在「请求数据」上得到←函数化 你觉得这优雅吗,我觉得一点也不,还非常麻烦和抽象,每一个「变换子」(即函数)都得绞尽脑汁才写出来,这些步骤也不可能比过程描述要少。 像 map 和 filter 这样的函数已经是函数式最适用的最小场合了,提供一个输入数组和输出数组的约束函数,把这个约束应用在原数组上得到新数组。这不函数化吗,不够优雅吗? |
4
walpurgis 2022-04-15 10:08:00 +08:00 1
去状态,首当其冲是减少 useState ,用 react query 或 swr 管理数据获取,getDetail 改成 return formData ,getDetail 就变成了一个伪纯函数,描述了 params 和 detail 的映射关系
这么做从根本上避免了在快速改变 params 时,多个协程都去 setDetail 产生的竞态问题 |