我目前正在使用Ramda library来构造新函数。下面是我的代码片段
function auth(operand) {
if (operand.prevResult.pass && operand.req.authenticated) {
return operand;
} else {
operand.prevResult.pass = false;
return operand;
}
}
function validate(operand) {
if (operand.prevResult.pass && operand.req.validated) {
return operand;
} else {
operand.prevResult.pass = false;
return operand;
}
}
function postHandle(operand) {
if (operand.prevResult.pass){
operand.res.send();
} else {
console.log('some error occured')
}
}
const doPost = R.pipe(auth, validate, postHandle);
//const doGet = R.pipe(auth, validate, getHandle);
//const doPatch ...etc
const req = {authenticated: true, validated: true};
const res = {send: () => {console.log('sent')}};
doPost({req, res, prevResult: {pass: true}});目标是能够使用一些共享方法创建doPost、doGet、doPatch etcs,比如身份验证/验证。
然而,我能找到的最好的函数是Ramda中的R.pipe。这样做是这样的
(((a, b, …, n) → o), (o → p), …, (x → y), (y → z)) → ((a, b, …, n) → z)
它只允许我在构造的函数中传入一个参数(例如,doPost,doGet)。因此,最后一行doPost({req, res, prevResult: {pass: true}});
我希望有一种方法可以让我传入三个参数。所以我可以在最后做doPost(req, res, {pass: true})。而且每个函数的签名也会看起来更好,就像function auth(req, res, prevResult),function validate(req, res, prevResult),function postHandle(req, res, prevResult)
发布于 2018-10-10 17:40:49
R.pipe:除第一个函数外,所有函数都将只接受一个参数。
我们可以通过使用curry函数R.curry来克服这个问题。
通常,curry函数会返回一个函数,直到它获得了函数签名中提到的所有参数。
创建auth、validate和postHandle的curried版本,如下所述。我希望这能解决你的问题。
const R = require('ramda');
const isPrevResultPass = R.propEq('pass', true);
const isAuthenticated = R.propEq('authenticated', true);
const isValidated = R.propEq('validated', true);
const updatePrevResultPass = R.assoc('pass');
const auth = R.curry((req, res, prevResult) => {
if (isPrevResultPass(prevResult) && isAuthenticated(req))
return prevResult;
return updatePrevResultPass(false, prevResult)
});
const validate = R.curry((req, res, prevResult) => {
if (isPrevResultPass(prevResult) && isValidated(req))
return prevResult;
return updatePrevResultPass(false, prevResult);
});
const postHandle = R.curry((req, res, prevResult) => {
if (R.not(isPrevResultPass(prevResult)))
console.log('some error occured')
res.send();
});
const req = {authenticated: true, validated: true};
const res = {send: () => {console.log('sent')}};
const prevResult = { pass: true };
const doPost = R.pipe(auth(req, res), validate(req, res), postHandle(req, res));
doPost(prevResult);发布于 2018-10-10 18:52:22
如果希望通过函数组合传递多个值,则需要能够从各个函数返回多个值。
要做到这一点,一种方法是使用一个像你这样的对象(尽管响应Shyam的注释来改变参数的结构,以帮助提高可读性)。
在一系列组合函数中的函数之间传输多个值的另一种方法是通过延续传递样式,其中所提供的回调期望接收多个结果。
const multiPipe = (...fns) => fns.reduceRight(
(pipe, next) => (...args) => next(...args)(pipe))
const fn = multiPipe(
(a, b) => k => k(a * 2, b * 3),
(a, b) => k => k(a - 5, b - 2)
)
fn(1, 2)((a, b) => console.log(a, b))
从continuation传递方式中获得的一个有趣功能是,您还可以缩短管道,以防止通过返回结果而不调用所提供的continuation来调用剩余的函数。
const multiPipe = (...fns) => fns.reduceRight(
(pipe, next) => (...args) => next(...args)(pipe))
const auth = (req, res) => next =>
req.authenticated
? next(req, res)
: console.log('authentication failed')
const validate = (req, res) => next =>
req.validated
? next(req, res)
: console.log('validation failed')
const postHandle = (req, res) => next =>
res.send()
const doPost = (req, res) =>
multiPipe(auth, validate, postHandle)(req, res)()
const req = { authenticated: true, validated: true }
const res = { send: () => console.log('sent') }
doPost(req, res)
https://stackoverflow.com/questions/52732373
复制相似问题