JavaScript中的Pipe

更新时间:2023-06-09 09:38:31 阅读: 评论:0

JavaScript中的Pipe
JavaScript中的Pipe
本⽂会介绍Pipe在函数式编程中的基本概念,怎么⽤Pipe让我们的代码变得更美好,以及新的pipe操作符,Fancy的东西在后⾯!
什么是Pipe?
先⽤⼀个最简单的例⼦来看⼀下什么是pipe,现在我们有两个最简单的函数addOne和addTwo,分别对于参数加⼀和加⼆:
const addOne = x => x + 1
const addTwo = x => x + 2
现在我们想让⼀个参数通过第⼀个函数之后再通过第⼆个函数,最直接最简单的⽅法是:
addTwo(addOne(1)) // 4
我们来写⼀个简单的pipe函数,它返回⼀个新的函数,来达到我们上⾯的⽬的:
const pipe = (func1, func2) => x => func2(func1(x))
const addThree = pipe(
addOne,
addTwo
)
addThree(1) // 4
嗯,现在还看不出来什么好处,但是当我们要经过的Transform越来越多的时候,这样的好处就会越来越明显:
const addTen = pipe(
addOne,
addTwo,
addThree,
addFour
)
所以我们需要⼀个更⽜逼的pipe函数,它可以接受任意数量的参数,并从第⼀个开始,依次接受原始数值,输出值传递给下⼀个函数。等等,我们好像想到了什么,遍历⼀个数组,把输出值当作下⼀个的输⼊,怎么听着都和reduce很像。所以,直接
⽤duce就可以写⼀个简单的pipe函数:
const pipe = ...args => x =>
(outputValue, currentFunction) => currentFunction(outputValue),
x
)
为什么要⽤Pipe
Pipe让我们将⼀些⼩功能随意的拼凑组合在⼀起,组成我们⾃⼰需要的功能。还记得React中的High Order Component(HOC)吗?越来越多的插件开始让你使⽤HOC,⽐如我经常遇到类似下⾯的代码:
// 没有pipe,
withRouter(
withTitle('Awesome title')(
translate('translations')(
connect(mapStateToProps, mapDispatchToProps)(培训瑜伽导师学校
Container
)
)
)
)
// 使⽤pipe
pipe(
connect(mapStateToProps, mapDispatchToProps),
translate('translations'),
withTitle('Awesome title'),
withRouter
)(Container)
// 使⽤pipe组成你需要的pattern
const withGeneralContainerProps = pipe(
connect(mapStateToProps, mapDispatchToProps),
translate('translations'),
withTitle('Awesome title'),
withRouter
)
生活大爆炸 第四季withGeneralContainerProps(Container)
Pipe和Prototype
在JavaScript中,经常有通过prototype进⾏的链式操作,⼀般来说这种代码如果在项⽬中看到还是挺喜闻乐见的,感觉代码还是⽐较⼲净,⽐如:
[1, 2, 3, 3, 5]
.map(i => i * 2)
.filter(i => i !== 10)
.reduce((acc, cur) => acc + cur)
但同时,基于prototype的这种链式操作是很难扩展的,⽐如我们想在上⾯的代码中间加⼀个新的操作符uniq,去除重复值:
// ⾂妾做不到。。。因为没有Array.prototype.uniq。。。pear怎么读
[1, 2, 3, 3, 5]
.map(i => i * 2)
.uniq()
.filter(i => i !== 10)
.reduce((acc, cur) => acc + cur)
// 有⼀种办法是在之前的某个地⽅改变prototype, 但你真的想这么做么?
Array.prototype.uniq = function () {
return Array.from(new Set(this))
}
不过如果我们把每个⼩函数拆开来,使⽤pipe,在保持代码清晰的同时,扩展性得到了巨⼤的提升,⽐如:
import * as R from 'ramda'
R.pipe(
学习英语的电影
R.map(i => i * 2),
找人帮忙R.uniq,
R.filter(i => i !== 10),
)([1, 2, 3, 3, 5])
更多关于Ramda可以参考或。同时要提⼀下的是,这也是为什么rxjs现在全改成了⽤pipe,⽽不使⽤prototype的原因。
等等,也许你并不需要Pipe?
刚才我们所做的其实都是在⽤functional programming的⽅式去写JavaScript,更彻底更优雅的解决⽅式,可能是在语法上的改变。已经在JavaScript中社区提出来⼀段时间了,但是具体⽅案还有分歧,可以去看Github Issue,这⾥我们就不说太多了,但是就算是基础版本的⽅案,个⼈觉得也是⾮常⼤的便利,⽽且如果你在⽤Babel,今天就可以开始使⽤。
按照添加插件,proposal先⽤minimal就好,等你弄清楚别的可以再尝试:
{
"plugins": [["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }]]
}
还是上⾯的例⼦:
import * as R from 'ramda'
[1, 2, 3, 4, 5]
|> R.map(i => i * 2)
cdrom
|> R.uniq
|> R.filter(i => i !== 10)
四级口语自我介绍|> R.reduce(R.add, 0)
// 是的,我们还可以写arrow function,
|> (_ => 'done, result is ' + _)
|> console.log
迪士尼英语官方网站或者是React的例⼦:suffer的用法
Container
siri是什么
|> connect(mapStateToProps, mapDispatchToProps)
|> translate('translations')
|> withTitle('Awesome title')
|> withRouter
哇塞,看的真是有点爽,JavaScript什么时候加⼀下简单说来:
a |>
b // b(a)
在Elixir,Ocaml等等的函数式语⾔中其实⼀直都有,⽽且社区对于怎么⽀持async function还有两个不同的提案,感兴趣的同学们都可以去尝试。
虽然只是写法上的不同,但是我相信这个改变的影响还是会⽐较深远的,语⾔的不同会慢慢导致⼤家思考问题的⽅式有细微的差异,期待这个提案尽快确定下来~
React都⽤Hook了,还要什么Class !
⼩编是⼀个有着5年⼯作经验的前端开发⼯程师,关于前端编程,⾃⼰有做材料的整合,⼀个完整的前端编程学习路线,学习材料和⼯具,+我的威信收取,免费送给tanzhou-10838⼤家,希望你也能凭着⾃⼰的努⼒,成为下⼀个优秀的程序员。

本文发布于:2023-06-09 09:38:31,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/910155.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:接受   代码   提案
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图