JavaScript调用多功能,但输入值从上一个函数输出

时间:2018-07-29 20:31:22

标签: javascript function methods ecmascript-6 functional-programming

我有这样的功能:

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)

7 个答案:

答案 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)

  • step case (对于长度为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') );

请记住,我记录了方法的传入参数,而不是结果值。这意味着例如secondFunlog: foo bar firstFun extra argument)的参数为'foo bar firstFun''extra argument'。但是当调用'secondFun'时,您只会看到添加的字符串thirdFun(因为它是作为参数给出的。)

答案 6 :(得分:-1)

错误方法-参见下文

如果您想要类似a.firstFunc().secondFunc().thirdFunc().fourthFunc()之类的东西,则应将这些函数定义为Object.prototype(或Number.prototypeString.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;
};