如何重用Javascript中的功能链?

时间:2019-04-30 20:01:43

标签: javascript functional-programming gremlin

我正在使用功能库(Gremlin)查询图形数据库。调用如下:

g.V().has(...).out(...).hasLabel(...).in(...).next();

我的某些功能链很长,我希望能够重用其中的一部分以用于DRY。例如:

const postProjection = () => (
  project("id", "title")
  .by(__.id())
  .by("title")
)

g.V().hasLabel("post").postProjection().next()

我知道这行不通,但这就是概念。我想将此链的一部分封装到一个函数中,我可以(以某种方式)在需要时将其注入该库的其他各种函数链中。通过使用可重用的段动态构建这些调用,我可以大大减少重复。

这可能吗?

2 个答案:

答案 0 :(得分:3)

如果要使用精确的语法来调用它,则必须使用类似this answer的功能向Vertex(或其他)原型添加函数。但是,这有点冗长,而且并不是解决此类问题的预期方法。我建议将其设置为常规函数调用,为此,除了需要参数之外,您现有的解决方案非常接近:

const postProjection = (vs) => (
  vs
  .project("id", "title")
  .by(__.id())
  .by("title")
)

const vs = g.V().hasLabel("post")
postProjection(vs).next()

答案 1 :(得分:0)

也许您可以使用实现functor并允许您调用内部对象的方法的类型:

const foo = i => (console.log(i), {foo, i});

const Box = o => ({
  map: f => Box(f(o)),
  run: (k, ...args) => Box(o[k] (...args)),
  get: o
});

const fun1 = o =>
  o.foo(3).foo(4)

const fun2 = o =>
  o.foo(7).foo(8);

console.log(
  Box(foo(1).foo(2))
    .map(fun1) // lift normal function into the type
    .run("foo", 5)
    .run("foo", 6)
    .map(fun2)
    .run("foo", 9)
    .get // escape from the type
    .foo(10));