是否有可能/建议重新使用lodash惰性对象?

时间:2016-01-29 23:23:30

标签: functional-programming lodash

我想知道是否建议传递并重新使用我用lodash创建的链式惰性对象。

var filtered = _(nonFiltered).filter(...).map(...);

filtered.each(doStuff).value();

var reMapped = filtered.map(...).object(...);

//keep using reMapped and filtered, sometimes calling .value()

以这种方式使用lodash链式对象是否安全?

1 个答案:

答案 0 :(得分:4)

是的,你绝对可以做到!

Lodash(> = v3.2)为您提供所需的所有工具。您可以自行决定何时执行链(通过调用.commit()(见下文)或通过显式或隐式调用.value()),您甚至可以通过注入不同的集合来重用以前创建的链/ array / objects / values(通过调用.plant()(见下文))。

然而,您应该考虑的是:

  1. 效果 --- 每次执行链时都会执行整个链。例如,在您的示例中,如果您执行reMapped链,则会再次执行初始filter()map()部分。即使您之前已经执行过filtered链。因此,在性能方面,在代码中的某个点执行链接并使用新的lodash包装器包装结果可能是有意义的。这就是commit()的用途。

    var filtered = _(nonFiltered).filter(...).map(...).commit();
    var reMapped = filtered.(...).commit();
    

    通过执行此操作,您将执行链并将结果包装在新的lodash包装器中。当然,这与plant()(见下文)并不一致。

    Click here for reference on commit()

  2. 可变生命周期 ---此外,在执行链时,您需要特别注意初始变量nonFiltered仍然指向同一个对象。即你不能创建你的链并期望nonFiltered的新任务能够自动地进入链中。这就是plant()的用途:

    reMapped.plant(nonFiltered).value();
    

    从技术上讲,在调用plant时,会克隆包装器,这会使原始包装器保持不变。在性能方面,克隆可以忽略不计。

    Click here for reference on plant()

  3. 内存管理 ---如果您过于自由地传递包装器,您可能会遇到nonFiltered变量(更确切地说是它指向的对象/数组)的情况)通常会被垃圾收集。但是,只要包装器存在,垃圾收集器就无法清理。这对您的内存占用只会产生一点影响,但是根据您创建的包装器数量以及存储它们的位置,这也可能意味着您最终可能会显着增加内存占用量,这取决于您最终发布包装器。

    最糟糕的情况,例如将包装器存储在某种长寿命对象上(例如存储在Angular服务中),包装重量级$ http响应的结果,可能包含大量不相关的数据,这些结果将减少到一小部分执行包装器时的原始大小。

    再次,commitplant来救援。您可以选择两种策略:

    1. 使用空值创建链(如:_().filter(...)...)并在执行链之前使用plant(参见(2。))。
    2. 或者在您定义链后立即commit(见(1。))