本文会介绍Pipe在函数式编程中的基本概念,怎么用Pipe让我们的代码变得更美好,以及新的pipe操作符,Fancy的东西在后面!
前不久我再对axios封装的时候,并利用了观察模式进行拦截器的应用。实现了类似webpack插件的扩展修改我们的axios。最近做response的处理的时候,我发现把代码都对接到then
里面处理也不是好的处理方式。
private httpClient(mode: Method, uri: string, body: any, options?: AxiosRequestConfig) {
const requestBody = ['GET', 'DELETE'].indexOf(mode) === 0 ?
{
params: body
}
:
{
data: body
}
return this.okHttp.getHttpClient().request({
...requestBody,
url: uri,
method: mode,
}).then(res => {
return res.data
})
}
这个时候我需要一种模式去解耦这种关系,如果还用观察者模式就过于复杂。使用rxjs的流式操作也不是不行,但是rxjs更偏向异步操作的顺序性。而我只是想流失koa这种洋葱(pipe)示例的操作。
如果你想流去做一件事情那么pipe
是一个不错的选择,可以把你的handle操作顺序放在其他地方动态的加载到then
里面操作。
什么是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很像。所以,直接用Array.prototype.reduce
就可以写一个简单的pipe
函数:
const pipe = ...args => x =>
args.reduce(
(outputValue, currentFunction) => currentFunction(outputValue),
x
)
当然在es6以上的写法可以简单符号完成。
a |> b // b(a)
代码改造
private httpClient(mode: Method, uri: string, body: any, options?: AxiosRequestConfig) {
const requestBody = ['GET', 'DELETE'].indexOf(mode) === 0 ?
{
params: body
}
:
{
data: body
}
return this.okHttp.getHttpClient().request({
...requestBody,
url: uri,
method: mode,
}).then(res => {
const response = ResponseHandle.getInstance().pipe(
AccessTokenHandle
)
response(res);
return res.data
})
}
可以看到我们使用以下代码来做以后我们的业务拓展,这里这是一个小例子自己举一反三。如果你是要进一步优化会如何操作,如果是我的话。pipe需要参数做成一个数组,这个数组可以做成配置项目,需要做那些校验和流的处理我们就要那个,在配置项目里面管理函数组合。
const response = ResponseHandle.getInstance().pipe(
AccessTokenHandle
)
response(res);
以后我们需要条件新的功能的时候,无需去看之前的屎山业务代码。添加一个就去配置一个,注意这里的pipe
是简单写法,如果你的业务有顺序性的话。应当注顺序组合。如果使用rxjs的话可以创建多个观察主题自己进行组合。
export function AccessTokenHandle(res: any) {
const { code } = res.data;
if (code === 1000) {
alert('数据不错喔!')
}
}
今天的项目的构建思维,就分享这么多。至于你们要怎么运用,要自己想想什么场景可以使用这种设计做处理。不是为了运用而运用!