我有这样的功能:
function intiFun(initValue) {
const firstResult = firstFun(initValue);
const secondResult = secondFun(firstResult);
const thirdResult = thirddFun(secondResult);
const fourthResult = fourthFun(thirdResult);
return fourthResult;
}
但是我想写得更好。而且我不想将每个函数的值保存为变量。
有什么解决方案可以在不保存旧值的情况下调用函数
类似于rxjs或类似的东西:
function intiFun(initValue) {
return firstFun(initValue).secondFun().thirddFun().fourthFun();
}
或更像这样的
function intiFun(initValue) {
return firstFun(initValue)
.secondFun(secondInput)
.thirddFun(secondInput)
.fourthFun(secondInput)
}
function secondFun(value, secondInput) {
return ...;
}
...
或一些自由地这样做(也许是lodash)
答案 0 :(得分:2)
我的猜测是您正在寻找函数组成:我们可以使用例如reduce
(例如,初始值为标识)从JavaScript中的函数数组构造复合函数函数(v) => v
:
const composeAll = (functions) => functions.reduce(
(composition, f) =>
((v) => f(composition(v))),
(v) => v
);
const firstFun = (s) => `${s}a`;
const secondFun = (s) => `${s}b`;
const thirdFun = (s) => `${s}c`;
const fourthFun = (s) => `${s}d`;
const intiFun = composeAll([firstFun, secondFun, thirdFun, fourthFun]);
console.log(intiFun(''));
输出:
abcd
注释:
如您所见,composeAll
通过将每个函数f
包装在带有值v
的箭头函数中来创建链式函数调用,并在由数组中的前一个函数,最后将结果传递到f
。
通过对数组长度进行归纳,可以使自己确信构造是正确的:如果我们将空函数列表的组成定义为标识函数,那么
在基本情况中(对于长度为1的单例数组[f]
),结果是
(v) => f((v => v)(v)) === (v) => f(v)
n
的数组)中的假设为数组中的n-1
先前函数获得的函数是正确构造的(让这是g
),那么结果是
(v) => f_n(g(v)) === (v) => f_n(f_n-1(...(f_0(v))...))
答案 1 :(得分:1)
您可以这样做
const firstFun = x => x + 1;
const secondFun = x => x + 1;
const thirdFun = x => x + 1;
const fourthFun = x => x + 1;
const pipe = (...functions) => x => functions.reduce((x, f) => f(x), x);
const initFun = pipe(firstFun, secondFun, thirdFun, fourthFun);
console.log(initFun(3));
答案 2 :(得分:1)
pipe
,手动计算和部分应用于救援:
const pipe = funs => x =>
funs.reduce ((o, fun) => fun (o), x)
const f = x => x + 1
const g = x => y => x + y * 2
const h = x => x * x
const i = x => y => z => x + y / z + 3
const j = x => x + 5
const init = pipe ([
f
,g (4)
,h
,i (10) (33)
,j
])
const input = 1
const output = init (input)
console.log (output)
答案 3 :(得分:1)
const firstFun = x => { /* return ... */ };
const secondFun = x => { /* return ... */ };
const thirdFun = x => { /* return ... */ };
const fourthFun = x => { /* return ... */ };
const callAll= (value, ...functions) => {
functions.forEach(fn => value = fn(value));
retrun value;
}
const result = callAll(3, firstFun, secondFun, thirdFun, fourthFun);
console.log(result);
答案 4 :(得分:0)
function initFun(initValue) {
return fourthFun(thirddFun(secondFun(firstFun(initValue))));
}
或者,将您的函数转换为promise:
function initFun(initValue) {
return firstFun(initValue)
.then(secondFun)
.then(thirddFun)
.then(fourthFun);
}
答案 5 :(得分:0)
您要查找的结果可以使用reduce
来实现。
let log = (head, ...args) => { console.log('log:', head, ...args); return head },
firstFun = (str, ...args) => log(str, ...args) + ' firstFun',
secondFun = (str, ...args) => log(str, ...args) + ' secondFun',
thirddFun = (str, ...args) => log(str, ...args) + ' thirddFun',
fourthFun = (str, ...args) => log(str, ...args) + ' fourthFun';
function initFun(initValue) {
let functions = [
[firstFun],
[secondFun, 'extra argument'],
[thirddFun],
[fourthFun, "I'm here too"],
];
return functions.reduce((result, [fn, ...args]) => fn(result, ...args), initValue);
}
console.log( 'result: ' + initFun('foo bar') );
请记住,我记录了方法的传入参数,而不是结果值。这意味着例如secondFun
(log: foo bar firstFun extra argument
)的参数为'foo bar firstFun'
和'extra argument'
。但是当调用'secondFun'
时,您只会看到添加的字符串thirdFun
(因为它是作为参数给出的。)
答案 6 :(得分:-1)
如果您想要类似 a.firstFunc().secondFunc().thirdFunc().fourthFunc()
之类的东西,则应将这些函数定义为Object.prototype
(或Number.prototype
,String.prototype
等):
Object.prototype.firstFunc = function() {
var value = this;
// ...
return something;
};
Object.prototype.secondFunc = function() {
var value = this;
// ...
return something;
};
Object.prototype.thirdFunc = function() {
var value = this;
// ...
return something;
};
Object.prototype.fourthFunc = function() {
var value = this;
// ...
return something;
};
P.S。 “功能”通常缩写为“ func”,而不是“ fun”。
如果您想要myObject(a).firstFunc().secondFunc().thirdFunc().fourthFunc()
之类的东西,则应该:
var myObject = function(value) {
this.value = value;
};
myObject.prototype.firstFunc = function() {
var value = this.value;
// ...
return something;
};
myObject.prototype.secondFunc = function() {
var value = this.value;
// ...
return something;
};
myObject.prototype.thirdFunc = function() {
var value = this.value;
// ...
return something;
};
myObject.prototype.fourthFunc = function() {
var value = this.value;
// ...
return something;
};