Ami*_*ole 4 functional-programming function-composition ramda.js
以下是我尝试将四个函数组合成一个端点字符串:
const endpoint = str => `${str}` || 'default'
const protocol = str => `https://${str}`
const params = str => `${str}?sort=desc&part=true&`
const query = str => `${str}query={ some:'value', another:'value'}`
let finalEndpoint = R.compose(query, params, protocol, endpoint)
var result = finalEndpoint('api.content.io')
Run Code Online (Sandbox Code Playgroud)
这个组合工作并返回我想要的结果:
https://api.content.io?sort=desc&part=true&query={ some:'value', another:'value'}
Run Code Online (Sandbox Code Playgroud)
但请注意我是如何对其函数体内部和内部的值进行硬编码的.我看到只有一个值超过了这个链中的值.paramsqueryR.compose
我如何以及在何处将参数传递给参数和查询参数?
更新:
我做的是curried那些函数:
var R = require('ramda');
const endpoint = str => `${str}` || 'default'
const protocol = str => `https://${str}`
const setParams = R.curry ( (str, params) => `${str}?${params}` )
const setQuery = R.curry ( (str, query) => `${str}&query=${JSON.stringify(query)}` )
Run Code Online (Sandbox Code Playgroud)
然后
let finalEndpoint = R.compose(protocol, endpoint)
var result = setQuery(setParams(finalEndpoint('api.content.io'), 'sort=desc&part=true'), { some:'value', another:'value'})
console.log(result);
Run Code Online (Sandbox Code Playgroud)
但最后的召唤result仍然看起来非常黑客和不优雅.有没有办法改善这个?
我如何以及在何处将参数传递给参数和查询参数?
老实说,你没有,不是在你使用Ramda或类似的库构建compose或pipe管道时.
Ramda(免责声明:我是作者之一)允许第一个函数接收多个参数 - 一些其他库执行,一些不执行 - 但后续函数只接收先前调用的结果.还有一个功能保护区,meld,这可能是与此有帮助的,但它确实有一个相当复杂的API.
但是,我真的不明白为什么你首先以这种方式构建这个功能.这些中间函数是否实际可重用,或者您是否按规范构建它们?我问的原因是,这似乎是同一个想法的一个更合理的版本:
const finalEndpoint = useWith(
(endpoint, params, query) =>`https://${endpoint}?${params}&query=${query}`, [
endpoint => endpoint || 'default',
pipe(toPairs, map(join('=')), join('&')),
pipe(JSON.stringify, encodeURIComponent)
]
);
finalEndpoint(
'api.content.io',
{sort: 'desc', part: true},
{some:'value', another:'value'}
);
//=> "https://api.content.io?sort=desc&part=true&query=%7B%22some%22%3A%22value%22%2C%22another%22%3A%22value%22%7D"
Run Code Online (Sandbox Code Playgroud)
我真的不知道你对最后一个参数的要求.没有它encodeUriComponent,我看起来很奇怪,但也许你不需要它.我还对第二个参数采取了自由,假设您更喜欢API中的实际数据到封装该数据的字符串.但是,如果你想通过'sort=desc&part=true',然后替换pipe(toPairs, map(join('=')), join('&'))用identity.
由于整个事情远非无点,我可能没有使用第一个函数的无点版本or(__, 'default'),因为我认为有更多可读性.
更新
您可以在Ramda REPL上看到这个版本,其中添加了一些console.log语句tap.
这确实为Ramda提出了一个有趣的问题.如果这些中间函数确实是可取的,那么Ramda无法将它们组合起来.显然拉姆达可以提供类似的东西meld,但是有中间立场吗?我想知道是否有一个有用的功能(当然是咖喱),我们应该包含类似的功能
someFunc([f0], [a0]); //=> f0(a0)
someFunc([f0, f1], [a0, a1]); //=> f1(f0(a0), a1)
someFunc([f0, f1, f2], [a0, a1, a2]); //=> f2(f1(f0(a0), a1), a2)
someFunc([f0, f1, f2, f3], [a0, a1, a2, a3]); //=> f3(f2(f1(f0(a0), a1), a2), a3)
// ...
Run Code Online (Sandbox Code Playgroud)
有一些严重的反对意见:如果名单长度不同怎么办?为什么初始调用是一元的,我们应该通过向函数添加单独的累加器参数来解决这个问题吗?尽管如此,这是一个有趣的功能,我可能会提出它来讨论Ramda板.
如果您有参数和查询作为柯里化函数,那么您可以:
编辑:具有所有花哨功能的代码,需要更改参数顺序或使用R.__和字符串化对象
const endpoint = R.curry( str => `${str}` || 'default' )
const protocol = R.curry( str => `https://${str}` )
const params = R.curry( (p, str) => `${str}?${p}` )
const query = R.curry( (q, str) => `${str}&query=${q}` )
let finalEndpoint =
R.compose(
query(JSON.stringify({ some:'value', another:'value' })),
params('sort=desc&part=true'),
protocol,
endpoint
)
var result = finalEndpoint('api.content.io')
console.log(result)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4250 次 |
| 最近记录: |