JavaScript中的链函数

时间:2019-01-10 22:27:54

标签: javascript node.js express-validator

有没有一种方法可以链接JavaScript中的函数,因此在调用链中的最后一个函数时,我们会考虑指定的链中的所有函数。 基本上我想做的是express-validator 确实: 像这样:

check('password').passwordValidator().optional();

我希望能够打电话

check('password').passwordValidator();

check('password').passwordValidator().optional();

4 个答案:

答案 0 :(得分:1)

所以您要寻找一种builder pattern?您可以这样做:

class Foo {
  _passwordValidator = false;
  _optional = false;

  passwordValidator() {
    this._passwordValidator = true;
    return this;
  }
  optional() {
    this._optional = true;
    return this;
  }

  doThing() {
    if (this._optional) { /* ... */ }
    if (this._passwordValidator) { /* ... */ }
  }
}

const foo = new Foo().passwordValidator().optional();

foo.doThing();

编辑:要更直接地回答您的问题,在当前方法调用链完成之前,没有办法等待做某事;您必须在示例中调用类似doThing()的方法,以表明您实际上现在想做这件事。

答案 1 :(得分:1)

调用express-validator的链接方法将返回一个中间件函数,并且由于函数可以具有属性,因此可以在该返回的函数上调用一个方法,该方法将返回带有方法的新函数,依此类推。链接功能非常简单:

 const chain = (pairs, fn = el => el) => {
   for(const [key, method] of pairs)
     fn[key] = (...opt) => chain(pairs, method(fn)(...opt));
   return fn;
};

const math = chain([
  ["add", prev => a => b => prev(b) + a],
  ["mul", prev => a => b => prev(b) * a]
]);

console.log(
  (math.add(5).mul(3).add(3))(5)
 );

答案 2 :(得分:1)

var Obj = {
  result: 0,
  addNumber: function(a, b) {
    this.result = a + b;
    return this;
  },

  multiplyNumber: function(a) {
    this.result = this.result * a;
    return this;
  },
 
  divideNumber: function(a) {
    this.result = this.result / a;
    return this;
  }
}

Obj.addNumber(10, 20).multiplyNumber(10).divideNumber(10);

链接 => here

答案 3 :(得分:0)

我最终使用了@ coolreader18的建议。 那正是我想要的。

function func(val) {
    var self = this;
    this._optional = false;
    this._check = false;

    const doStaff = (message = 'Doing staff') => {
        console.log(message);
        return;
    };


    return {
        check: function(n) {
            this._check = true;
            return this;
        },
        optional: function(n) {
            this._check = false;
            this._optional = true;
            return this;
        },
        exec: function() {
            if (this._check) doStaff();
            if (this._optional) doStaff('Maybe not');
        }
    }
}

func().check().optional().exec();