2013-07-17 37 views
8

Theo các nguồn tin Underscore.JS (https://github.com/jashkenas/underscore/blob/master/underscore.js):Tại sao phương thức chain() Underscore.js không phải là lười?

// 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; 
} 

chuỗi() và giá trị() chức năng là giấy gói chỉ đơn giản cho đối tượng dấu gạch dưới.

Vì vậy, nếu tôi đang sử dụng sau khi xây dựng:

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

gạch sẽ tạo ra hai bộ sưu tập trung và sẽ thực hiện ba kiểu liệt kê.

Tại sao các phương thức chain() và value() không được triển khai như được đánh giá lười biếng như LINQ thực hiện các phương thức của nó? Ví dụ: chuỗi này có thể được coi là:

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

Có bất kỳ vấn đề nào liên quan đến JS đối với loại triển khai này không?

Trả lời

12

Về cơ bản để làm cho mô hình .chain() lười biếng theo cách bạn mô tả, nó sẽ yêu cầu phải có gần hai phiên bản của mỗi phương pháp. Bạn sẽ cần các phương thức phản hồi ngay lập tức làm những gì tài liệu nói (trả về một mảng) và bạn sẽ cần các phương thức lười biếng để đánh giá lười (trả về một hàm mong đợi để chạy sau này cho mỗi phần tử).

Một cách để thực hiện điều này là viết tất cả dấu gạch dưới là lười và hiển thị dưới dạng dấu gạch dưới bị xích. Sau đó, hiển thị dấu gạch dưới bình thường như một wrapper của gạch dưới lười biếng mà gọi là gạch dưới lười biếng, ngay lập tức đánh giá, và sau đó trả về kết quả. Có hai vấn đề chính: (1) đó là công việc nhiều hơn và (2) đó là một kiến ​​trúc hoàn toàn trái ngược đòi hỏi tất cả các dấu gạch dưới được viết là lười biếng chỉ để hỗ trợ đánh giá lười biếng của phương pháp chuỗi. Nó chắc chắn có thể làm được, như được trưng bày bởi JSLinq và .NET LINQ, nhưng có một chi phí rất lớn về thời gian phát triển để phát triển và bảo trì, cũng như tăng độ phức tạp và khả năng lỗi. Dấu gạch dưới cung cấp đánh giá không lười biếng của 80 phương pháp tiện ích khác nhau trong 1.200 dòng mã. JSLinq cung cấp đánh giá lười biếng của 21 phương pháp tiện ích khác nhau trong 7.000 dòng mã. Nhiều mã hơn, số lượng hàm thấp hơn.

Có giao dịch. Mỗi nhà phát triển sẽ đưa ra quyết định của riêng họ (miễn là họ đang làm việc cho chính họ).

7

Tôi tin rằng bạn đang tìm kiếm cái gì đó như Lazy.js:

Lazy.js là một thư viện tiện ích cho JavaScript, tương tự như gạch dưới và Lo-Dash nhưng với một sự khác biệt quan trọng: đánh giá lười biếng (hay còn gọi là trì hoãn thực hiện). Điều này có thể chuyển thành hiệu năng vượt trội trong nhiều trường hợp, đặc biệt là khi xử lý các mảng lớn và/hoặc "chuỗi" cùng nhiều phương thức. Đối với các trường hợp đơn giản (map, filter, v.v.) trên các mảng nhỏ, hiệu suất của Lazy phải tương tự như Gạch dưới hoặc Dấu gạch ngang.

Chỉnh sửa: Dường như Lo-Dash may be adding the ability to do lazy evaluation.