Generatori: elementi nocivi

Jacopo Posnick
Jacopo Posnick

La specifica bozza ECMAScript 6 ha già generato molte soddisfazioni per gli sviluppatori JavaScript moderni. Abbiamo esaminato alcuni nuovi corsi di raccolte e for..of loop di iterazione in un post precedente. In questo post, parleremo di un aspetto che va di pari passo con i loop di for..of: le funzioni del generatore.

Esiste già un host di ottimo materiale che spiega perché e come utilizzare i generatori. In breve, i generatori sono funzioni speciali che creano iteratori, mentre gli iteratori sono oggetti che hanno un metodo next(), che può essere chiamato per ottenere un valore. All'interno di una funzione generatore, la parola chiave yield fornisce il valore per next(). L'uso di yield sospende l'esecuzione della funzione generatore, mantenendo lo stato fino alla chiamata di next() di nuovo, dopodiché il codice viene riavviato e continua, finché yield non restituisce un altro valore (o fino a quando la funzione del generatore non termina). Esistono diversi casi d'uso canonici per le funzioni del generatore, ad esempio il loro utilizzo per iterare sui numeri nella sequenza di Fibonacci.

Una volta escluse le basi, approfondiamo un po' con un esempio JavaScript che illustra alcuni dei trucchi del mestiere, o "gnarly bit", legati all'uso dei generatori. La sezione contiene molti commenti e puoi provare la versione pubblicata del codice prima di leggerla:

Quali sono alcuni importanti concetti chiave del codice?

In primo luogo, la creazione di un generatore genera un iteratore univoco con il suo stato distinto; puoi trasferire i parametri al costruttore del generatore che può controllare il comportamento.

In secondo luogo, puoi passare un parametro quando chiami il metodo next() di un iteratore e quel valore verrà assegnato a ciò che si trova sul lato sinistro dell'istruzione yield della precedente chiamata all'iteratore. Questo è un ottimo modo per variare l'output dell'iteratore. Qui lo usiamo per controllare se la parola restituita è in maiuscolo o meno. Se vuoi influenzare il primo valore restituito, esegui l'operazione tramite un parametro per il costruttore del generatore.

Infine, i generatori possono produrre iteratori finiti o infiniti. Se lavori con un iteratore infinito, assicurati di avere una sorta di condizione di terminale basata sul valore yielded: è molto facile scrivere loop infiniti per errore, soprattutto quando utilizzi for..of per l'iterazione. Se utilizzi un iteratore finito tramite chiamate a next(), la proprietà .done dell'oggetto che ha restituito indica se l'iterazione è stata completata.

Ci auguriamo che questo esempio, insieme alle altre risorse disponibili sul Web, generi entusiasmo e vi aiuti a riflettere su come utilizzare i generatori nel vostro codice. Le versioni di Firefox a partire dalla 31 e di Chrome che iniziano con 39 supportano i generatori nativi. Il progetto Regenerator offre supporto del generatore per altri browser e l'utilizzo di Traceur è un'opzione.

Grazie a Erik Arvidsson per il suo aiuto nella revisione di questo articolo.