2013-07-17 6 views
8

Secondo fonti Underscore.JS (https://github.com/jashkenas/underscore/blob/master/underscore.js):Perché il metodo Underscore.js chain() non è pigro?

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

catena() e value() funzioni sono solo semplici involucri per oggetto sottolineatura.

Quindi, se sto usando seguente costruzione:

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

sottolineatura creerà due collezioni intermedi ed effettuerà tre enumerazioni.

Perché i metodi chain() e value() non vengono implementati come valutati pigri come se LINQ implementasse i suoi metodi? Ad esempio, questa catena può essere trattata come:

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

Esiste qualche problema relativo a JS per questo tipo di implementazione?

risposta

12

Fondamentalmente per rendere il .chain() pigro come descritto, occorrerebbe avere quasi due versioni di ciascun metodo. Avresti bisogno dei metodi di risposta immediata che fanno ciò che dice la documentazione (restituisce un array) e avresti bisogno dei metodi pigri che fanno la valutazione lazy (restituisce una funzione che si aspetta di essere eseguita successivamente per ciascun elemento).

Un modo per implementare questo sarebbe scrivere tutto il carattere di sottolineatura come pigro ed esporre questo come carattere di sottolineatura concatenato. Quindi esponi il carattere di sottolineatura normale come un wrapper di carattere di sottolineatura lazy che richiama il carattere di sottolineatura pigro, valuta immediatamente e restituisce i risultati. Ci sono due problemi principali: (1) è molto più lavoro e (2) è un'architettura completamente opposta che richiede che tutto il carattere di sottolineatura sia scritto come pigro solo per supportare la valutazione pigra del metodo di catena.

È certamente fattibile, come dimostrato da JSLinq e LINQ di .NET, ma c'è un costo enorme in termini di tempo di sviluppo per lo sviluppo e la manutenzione, oltre a una maggiore complessità e probabilità di bug. Underscore fornisce una valutazione non pigra di 80 diversi metodi di utilità in 1.200 linee di codice. JSLinq fornisce una valutazione lazy di 21 diversi metodi di utilità in 7000 righe di codice. Molto più codice, minore quantità di funzioni.

C'è un compromesso. Ogni sviluppatore prende le proprie decisioni (purché stiano lavorando per se stesse).

7

Credo che stai cercando qualcosa di simile Lazy.js:

Lazy.js è una libreria di utilità per JavaScript, simile per sottolineare e Lo-Dash, ma con una differenza importante: la valutazione pigra (noto anche come esecuzione differita). Questo può tradursi in prestazioni superiori in molti casi, specialmente quando si ha a che fare con array di grandi dimensioni e/o "concatenare" insieme più metodi. Per casi semplici (map, filter, ecc.) Su piccoli array, le prestazioni di Lazy dovrebbero essere simili a Underscore o Lo-Dash.

Edit: apparire come se Lo-Dash may be adding the ability to do lazy evaluation pure.