考虑以下示例
function doSomethingToAVariable(variable){
return variable + 1
}
function doSomethingToAVariableASecondTime(variable){
return variable + 2
}
function doSomethingToAVariableLastly(variable){
return variable + 3
}
var myVariable = 0;
myVariable = doSomethingToAVariable(myVariable);
myVariable = doSomethingToAVariableASecondTime(myVariable);
myVariable = doSomethingToAVariableLastly(myVariable);
console.log(myVariable); // 6
如何避免令人讨厌的myVariable重新声明?可以将每个函数包装到Promise链中作为解决方案吗?
答案 0 :(得分:2)
救援的功能组成。
看一下函数式编程库,比如Ramda或lodash-fp。
这里有一个简单的JS片段来组成函数:
//the compose-method you find in your regular FP-libs
var compose = (...funcs) => (value) => funcs.reduceRight((v,fn)=>fn(v), value);
//or a function wich takes the functions in opposite order,
//wich might be more common to you
var pipe = (...funcs) => (value) => funcs.reduce((v,fn)=>fn(v), value);
compose是您尝试构建的作品的直接映射
var composition = (value) => a(b(c(value)));
var composition = compose(a, b, c);
//it calls the functions from right to left
管道更倾向于您已知的命令式样式,以逐步处理值
var composition = function(value){
value = c(value);
value = b(value);
value = a(value);
return value;
}
//pipe the value through c, then through b, then through a
var fn = pipe(c, b, a);
//wich in the end does exactly the same as the code built by compose
回到你的代码:
var composition = pipe(
doSomethingToAVariable,
doSomethingToAVariableASecondTime,
doSomethingToAVariableLastly
);
//or
var composition = compose(
doSomethingToAVariableLastly,
doSomethingToAVariableASecondTime,
doSomethingToAVariable
);
//and run it
var myVariable = composition(0);
答案 1 :(得分:1)
如果你想链接,那么你需要返回包含最终值
的对象function variableOperations( initialValue )
{
this.value = initialValue;
this.someOp1 = function(){ this.value += 1; return this; }
this.someOp2 = function(){ this.value += 2; return this; }
}
var a = new variableOperations(1); //new object
a.someOp1().someOp2();
alert(a.value); //alerts 4
答案 2 :(得分:0)
在这种情况下,您正在寻找所谓的“功能组合”:
var myVariable = doSomethingToAVariableLastly(doSomethingToAVariableASecondTime(doSomethingToAVariable(0)));
但使用如此长的函数名称显然无法读取。
Promise通常仅对异步操作有用,虽然它们在这种情况下工作,但结果效率低下并且会在不需要的情况下引入异步依赖:
var promise = doSomethingToAVariable(0);
.then(doSomethingToAVariableASecondTime);
.then(doSomethingToAVariableLastly);
因为您只能访问.then
回调链末尾的最终结果:
promise.then(function(myVariable) {
// myVariable is now 6, and in scope
}
// but it's not in scope or usable here
答案 3 :(得分:0)
为什么不看看Ramda的功能方法?
R.compose(
doSomethingToAVariableLastly,
doSomethingToAVariableASecondTime,
doSomethingToAVariable
)(myVariable)
答案 4 :(得分:0)
以我的拙见,你的代码非常好。
但是,如果你真的想要“链接”这些电话,你可以做这样的事情。但效率稍差。
function chainCalls(initVal, funcs){
return funcs.reduce(function(val, f){
return f(val);
}, initVal || 0);
}
function doSomethingToAVariable(variable){
return variable + 1
}
function doSomethingToAVariableASecondTime(variable){
return variable + 2
}
function doSomethingToAVariableLastly(variable){
return variable + 3
}
var myVariable = chainCalls(0, [doSomethingToAVariable,
doSomethingToAVariableASecondTime,
doSomethingToAVariableLastly]);
document.write(myVariable);
另一种方法是创建一个像这样的可重用函数链。
function functionChain(){
var funcs = arguments;
return function(value){
return Array.prototype.reduce.call(funcs, function(value, f){
return f(value);
}, value);
};
}
function doSomethingToAVariable(variable){
return variable + 1
}
function doSomethingToAVariableASecondTime(variable){
return variable + 2
}
function doSomethingToAVariableLastly(variable){
return variable + 3
}
var myVariable = functionChain(
doSomethingToAVariable,
doSomethingToAVariableASecondTime,
doSomethingToAVariableLastly
)(0);
document.write(myVariable);
答案 5 :(得分:0)
如果将一些东西放在一起就像递归方法一样简单。有点像使用promises但没有实际使用它们。
function add(x) {
return {
done: () => x,
add: (y) => add(x + y)
}
}
let myVariable = 0;
add(myVariable).add(1).add(2).add(3).done(); // 6