简体   繁体   English

为什么Underscore.js chain()方法不是惰性的?

[英]Why Underscore.js chain() method is not lazy?

According to Underscore.JS sources ( https://github.com/jashkenas/underscore/blob/master/underscore.js ): 根据Underscore.JS来源( https://github.com/jashkenas/underscore/blob/master/underscore.js ):

// Start chaining a wrapped Underscore object.
chain: function() {
  this._chain = true;
  return this;
},

// Extracts the result from a wrapped and chained object.
value: function() {
  return this._wrapped;
}

chain() and value() functions are just simple wrappers for Underscore object. chain()和value()函数只是Underscore对象的简单包装。

So if I'm using following construction: 因此,如果我使用以下构造:

_.chain(someCollection)
.map(function1)   
.map(function2)
.map(function3)
.value()

Underscore will create two intermediate collections and will perform three enumerations. 下划线将创建两个中间集合,并将执行三个枚举。

Why the chain() and value() methods are not implemented as lazy evaluated like LINQ implements its methods? 为什么不像LINQ那样实现对lazy的求值,就没有实现chain()和value()方法? For example, this chain could be treated as: 例如,该链可以视为:

_.chain(someCollection)
.map(function(x){
    return function3(function2(function1(x)));
})
.value();

Is there any JS related issues for this kind of implementation? 这种实现是否存在与JS相关的问题?

Basically to make .chain() lazy the way you describe, it would require having almost two versions of each method. 基本上使.chain()像您描述的那样懒惰,这将需要每个方法具有几乎两个版本。 You would need the immediate response methods that do what the documentation says (returns an array) and you would need the lazy methods that do lazy evaluation (returns a function expecting to be run later for each element). 您将需要执行文档中所说的立即响应方法(返回一个数组),并且您需要执行延迟计算的延迟方法(返回一个期望稍后对每个元素运行的函数)。

One way to implement this would be to write all of underscore as lazy and expose this as the chained underscore. 一种实现方法是将所有下划线写为惰性,并将其公开为链接的下划线。 Then expose normal underscore as a wrapper of lazy underscore that calls lazy underscore, immediately evaluates, and then returns the results. 然后将普通下划线暴露为调用“下划线”的下划线的包装,立即求值,然后返回结果。 There's two main problems: (1) it's a lot more work and (2) it's a completely opposite architecture requiring all of underscore to be written as lazy just to support lazy evaluation of the chain method. 主要有两个问题:(1)要做的工作还很多;(2)这是完全相反的体系结构,要求将所有下划线都编写为lazy,以支持对chain方法的lazy评估。

It's certainly doable, as exhibited by JSLinq and .NET's LINQ, but there's a huge cost in terms of developer time for development and maintenance, as well as increased complexity and likelihood of bugs. 正如JSLinq和.NET的LINQ所展示的那样,这当然是可行的,但是就开发人员进行开发和维护的时间而言,这付出了巨大的代价,而且还增加了错误的复杂性和可能性。 Underscore provides non-lazy evaluation of 80 different utility methods in 1,200 lines of code. Underscore在1200行代码中提供了80种不同实用方法的非惰性评估。 JSLinq provides lazy-evaluation of 21 different utility methods in 7,000 lines of code. JSLinq在7,000行代码中提供了21种不同实用方法的延迟评估。 A lot more code, lower quantity of functions. 更多的代码,更少的功能。

There's a trade off. 有一个权衡。 Each developer gets to make their own decisions (as long as they're working for themselves). 每个开发人员都可以做出自己的决定(只要他们为自己工作)。

I believe you're looking for something like Lazy.js : 我相信您正在寻找Lazy.js之类的东西

Lazy.js is a utility library for JavaScript, similar to Underscore and Lo-Dash but with one important difference: lazy evaluation (also known as deferred execution). Lazy.js是JavaScript的实用程序库,类似于Underscore和Lo-Dash,但有一个重要的区别:懒惰求值(也称为延迟执行)。 This can translate to superior performance in many cases, especially when dealing with large arrays and/or "chaining" together multiple methods. 在许多情况下,这可以转化为卓越的性能,尤其是在处理大型数组和/或“链接”多种方法时。 For simple cases ( map , filter , etc.) on small arrays, Lazy's performance should be similar to Underscore or Lo-Dash. 对于小型阵列上的简单情况( mapfilter等),Lazy的性能应类似于Underscore或Lo-Dash。

Edit : It look as though Lo-Dash may be adding the ability to do lazy evaluation as well. 编辑 :看起来Lo-Dash可能还添加了进行惰性评估的功能

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM