Uso avanzato di CoffeeScript

Sommario
Nei tutorial passati stavamo lavorando con le classi, rendendo così la nostra applicazione più modulare, stavamo anche vedendo in modo approfondito come eseguire il lavoro asincrono usando CoffeeScript come lingua, offrendoci così una gamma più ampia di opzioni per lavorarci.
Dopo aver padroneggiato questi concetti, è tempo di fare un passo avanti e utilizzare ciò che sappiamo per scrivere codice più pulito, più funzionale e ovviamente più potente. È tempo di imparare come diventare utenti esperti di CoffeeScript.
Ora che sappiamo come usare le classi nella nostra applicazione, è solo questione di tempo prima che si verifichino problemi. contesto. Quando siamo con funzioni semplici è abbastanza facile vedere quali dati ha questa funzione nel suo ambito, conosce le variabili globali, le variabili definite all'interno della funzione e qualsiasi variabile definita nell'ambito locale quando è stata creata la funzione.
Ma quando i metodi sono legati agli oggetti, questo diventa un po' più complicato. Per illustrare questo, vediamo un esempio in cui possiamo vedere questo problema e poi vedremo come CoffeeScript può aiutarci:
 class Sollevamento dell'ancora della nave: (doneCallback) -> console.log "Sollevamento dell'ancora". setVel: (speed) -> console.log "Setting speed to # {speed}" salpiamo: -> @levantarAncla @ fixVel 70
Supponiamo quindi secondo il nostro codice di voler salpare immediatamente, per questo facciamo quanto segue per invocare la nostra funzione:
 bot = nuovo Barco bot.zarpar ()
Se osserviamo da vicino e trasferiamo questo codice nel mondo reale, possiamo renderci conto che il sollevamento dell'ancora non avviene immediatamente, dobbiamo aspettare che l'ancora sia completamente sollevata per poter salpare. Possiamo risolvere questo problema aggiungendo a richiama e chiedendo se è stato completato, così sapremo quanto tempo impiega questa azione e chiameremo la nostra funzione una volta terminata, vediamo:
 liftAnchor: (doneCallback) -> console.log "Sollevare ancora." se fatto Richiamare? setTimeout doneCallback, 1000
Come possiamo vedere, stiamo invocando il callback solo se esiste, in questo modo ci assicuriamo che questo processo sia completato e quindi dobbiamo modificare la nostra funzione salpare:
 salpare: -> @levantarAncla -> @ fixVel 70
Ora quello che facciamo è invocare la funzione salpare Dopo aver sollevato l'ancora, questo assicura che non ci sposteremo fino a quando l'ancora non sarà completamente sollevata. Sembra abbastanza buono, compileremo il nostro codice e includeremo il file .js generato in un HTML per vedere la risposta dalla console:

Come vediamo nell'immagine abbiamo ottenuto un errore in cui si dice che la funzione non esiste. Cosa è successo? è molto semplice, JavaScript ha impostato il valore Este nel modo in cui è stata invocata la funzione, poiché quando si chiama bot.zarpar il valore Este è legato all'oggetto bot, quindi questo è legato al contesto globale e questo non è quello che vogliamo.
Quello che vogliamo fare è assicurarci che Este è sempre legato all'istanza di bot all'interno del corpo del callback e siamo fortunati, poiché CoffeeScript ha una funzionalità per quel caso. Per questo dichiareremo la funzione con freccia grassa o freccia spessa, in questo modo la funzione avrà il Este legato al contesto in cui è stato dichiarato, vediamo come si presenta il nostro codice con questa modifica:
 class Sollevamento dell'ancora della nave: (doneCallback) -> console.log "Sollevamento dell'ancora". se fatto Richiamare? setTimeout doneCallback, 1000 setVel: (speed) -> console.log "Setting speed to # {speed}" salpiamo: -> @levantarAncla => @fixVel 70 bot = new Barco bot.zarpar ()
Compiliamo il nostro file e vediamo come CoffeeScript Legame degli obiettivi con la funzionalità freccia spessa:

Cosa fa CoffeeScript prima di dichiarare il richiama è impostare una variabile locale _Este, che si riferisce a Este, poiché anche se il richiama è legato dinamicamente al valore carica ancora il contesto locale in cui è stato dichiarato. Infine, eseguiremo il nostro file generato e poi vedremo come è stato risolto l'errore:

Avendo già visto come risolvere il problema del contesto nelle nostre applicazioni con CoffeeScript Vedremo una tecnica abbastanza semplice ma potente per aiutarci a risparmiare lavoro. Non è una tecnica avanzata ma è un modo logico per apportare un miglioramento al nostro codice senza troppi sforzi da parte nostra.
MemoizzazioneQual è la tecnica di memorizzazione è memorizzare i valori di una funzione invece di ricalcolarli ogni volta che la funzione viene chiamata. Ora che sappiamo come usare classi e oggetti, possiamo usare questa conoscenza per applicarli all'interno CoffeeScript e utilizzare la tecnica in questione.
Ci sono molti modi per eseguire il processo di memorizzazione, nel caso di questo tutorial manterremo le cose semplici. Per questo, ciò che faremo è che quando verranno richieste determinate informazioni, verificheremo se sono archiviate, in tal caso le restituiamo immediatamente, altrimenti possiamo calcolarle e salvarle per un uso futuro. Questa tecnica è estremamente utile quando dobbiamo utilizzare un algoritmo complesso per ricevere una risposta o nel caso in cui utilizziamo una rete lenta per ottenere informazioni.
Quindi diamo un'occhiata al codice per illustrare questa tecnica:
 class Rocket getPath: -> @path? = @doMathComplexProcess ()
Per spiegare meglio questa porzione di codice la compileremo per vedere come CoffeeScript costruire il JavaScript che la nostra tecnica dovrà risparmiarci lavoro nel nostro sviluppo, vediamo come si presenta il nostro codice:

INGRANDIRE

Come possiamo vedere nel nostro codice, il calcolo della traiettoria verrà effettuato solo la prima volta che richiesta e il valore memorizzato verrà utilizzato d'ora in poi. Potremmo anche vedere nel nostro codice CoffeeScript che abbiamo avuto l'aiuto dell'operatore terziario ?= che valuterà l'espressione nel caso in cui il percorso sia nullo, inoltre avremo aiuto dal ritorno implicito delle funzioni che restituiranno il risultato dell'espressione, in questo caso il valore di @traiettoria se è stato precedentemente memorizzato o è stato appena calcolato.
Ma questo non è tutto ciò che possiamo fare con la nostra nuova tecnica in CoffeeScript, possiamo anche memorizzare più di un valore utilizzando una struttura dati, vediamo come possiamo farlo:
 class SecurityGateway hasAccess: (guard) -> @access? = {} @access [guard.plate_number]? = verificareCredentials guard.plate_number
Ciò che fa questa porzione di codice è che nel nostro oggetto il risultato viene memorizzato per ogni guardia che ha richiesto l'accesso, avremmo solo bisogno di qualcosa di unico per poterli identificare nel nostro oggetto, quindi usiamo il numero di targa per questo compito, vediamo come viene tradotto il nostro codice quando lo compiliamo:

INGRANDIRE

È importante ricordare che questa tecnica dovrebbe essere utilizzata solo con informazioni che non cambieranno durante l'esecuzione del nostro programma, nel caso in cui lo fosse, si consiglia di implementare una soluzione basata su cache.
Infine vedremo un modo per passare le opzioni a una funzione, questa non è una funzionalità speciale di CoffeeScriptÈ più che altro una convenzione che fa uso di molte delle caratteristiche del linguaggio, utilizzandole in uno schema di facile comprensione e altrettanto utile in molte situazioni che possono presentarsi.
Come funziona?L'idea alla base è semplice, è avere una funzione che lo accetti oggetto opzioni che può contenere chiavi associative per gli argomenti di quella funzione. Questo rende le opzioni facili da capire dal codice in cui vengono chiamate perché ci sono parentesi graffe per identificare cosa fa ogni valore. Ciò riduce anche il fastidio di tenere d'occhio gli argomenti e il loro ordine, poiché le chiavi dell'oggetto non dipendono da questo e possono essere omesse se non necessarie.
Per implementare il oggetti opzioni per prima cosa useremo argomenti facoltativi per impostare di default un argomento vuoto. In questo modo, quando si effettua la chiamata, possiamo omettere le opzioni nel caso in cui i valori non siano necessari:
 launchNave = (name, options = {}) -> return if options.drift dry take off ()
Ora useremo l'operatore terziario ?= per compilare i valori delle opzioni che vogliamo avere un valore predefinito speciale:
 launchNave = (name, options = {}) -> options.count? = 10 console.log "# {i}…" for i in [options.count… 0] return if options.drift dry take off ()
Definiamo un ultimo valore e usiamo l'operatore ? nel caso venga utilizzato in un unico luogo:
 launchSave = (name, options = {}) -> checkFuel (options.waitComb? 100) options.count? = 10 console.log "# {i}…" for i in [options.count… 0] restituisce if options. decollo a secco ()
Infine approfittiamo della sintassi permissiva di CoffeeScript per inviare le opzioni alla nostra funzione senza le parentesi, dandoci una chiamata abbastanza semplice e naturale:
 launchShip "Millennium Falcon", DryGear: true, conto alla rovescia: 15
Per finire compileremo il nostro file e vedremo l'output del nostro codice in JavaScript:

INGRANDIRE

Con quest'ultimo abbiamo terminato questo tutorial, dove abbiamo potuto imparare non solo modi avanzati di utilizzo CoffeeScript ma piuttosto tecniche che ci aiuteranno a scrivere codice migliore, che con l'uso e la ricerca costanti possiamo diventare sviluppatori migliori che utilizzano le migliori pratiche per lo sviluppo di applicazioni.
wave wave wave wave wave