Avanceret brug af CoffeeScript

Indholdsfortegnelse
I tidligere tutorials arbejdede vi med klasser, hvilket gjorde vores applikation mere modulær, vi så endda i dybden, hvordan vi udfører asynkront arbejde ved hjælp af CoffeeScript som sprog, hvilket giver os en større række muligheder for at arbejde med det.
Efter at have mestret disse begreber, er det tid til at gå et skridt videre og bruge det, vi ved, til at skrive renere, mere funktionel og selvfølgelig mere kraftfuld kode. Det er på tide at lære at blive magtbrugere af CoffeeScript.
Nu hvor vi ved, hvordan vi bruger klasser i vores applikation, er det kun et spørgsmål om tid, før vi støder på problemer med det. sammenhæng. Når vi er med enkle funktioner, er det ganske let at se, hvilke data denne funktion har i sit omfang, den kender globale variabler, variabler defineret inden for funktionen og enhver variabel, der blev defineret i det lokale omfang, da funktionen blev oprettet.
Men når metoderne er bundet til objekter, bliver dette lidt mere kompliceret. For at illustrere dette, lad os se et eksempel, hvor vi kan se dette problem, og så vil vi se hvordan CoffeeScript kan hjælpe os:
 klasse Skibs løfteanker: (doneCallback) -> console.log "Løfteanker." setVel: (speed) -> console.log "Indstilling af hastighed til # {speed}" sætter sejl: -> @levantarAncla @ fixVel 70
Antag så ifølge vores kode, at vi vil sejle med det samme, for dette gør vi følgende for at påkalde vores funktion:
 bot = ny Barco bot.zarpar ()
Hvis vi ser godt efter og overfører denne kode til den virkelige verden, kan vi indse, at løft af ankeret ikke sker med det samme, vi må vente på, at ankeret er fuldt hævet for at kunne sejle. Vi kan løse dette problem ved at tilføje en ring tilbage og spørger, om den er afsluttet, så vi ved, hvor lang tid denne handling tager og kalder vores funktion, når den er færdig, lad os se:
 liftAnchor: (doneCallback) -> console.log "Løfteanker." hvis det er gjortCallback? setTimeout doneCallback, 1000
Som vi kan se, påkalder vi kun tilbagekald, hvis det findes, på denne måde sikrer vi, at denne proces er afsluttet, og derfor skal vi ændre vores funktion sæt sejl:
 sæt sejl: -> @levantarAncla -> @ fixVel 70
Det vi gør nu er at påkalde funktionen sæt sejl Efter at have løftet ankeret sikrer dette, at vi ikke bevæger os, før ankeret er helt hævet. Dette ser ret godt ud, vi skal kompilere vores kode, og vi vil inkludere den genererede .js -fil i en HTML for at se svaret efter konsol:

Som vi ser på billedet har vi fået en fejl, hvor der står, at funktionen ikke findes. Hvad skete der? Det er meget enkelt, JavaScript har angivet værdien Este på den måde, hvorpå funktionen er blevet påkaldt, siden da der blev ringet op bot.zarpar værdien Este er knyttet til objektet bot, så dette er bundet til den globale kontekst, og det er ikke det, vi ønsker.
Det, vi vil gøre, er at sikre det Este er altid knyttet til forekomsten af bot inde i tilbagekaldelsens krop, og vi har held og lykke siden CoffeeScript den har en funktionalitet til den sag. Til dette vil vi erklære funktionen med fed pil eller tyk pil, på denne måde vil funktionen have Este knyttet til den kontekst, hvor den blev erklæret, lad os se, hvordan vores kode ser ud med denne ændring:
 klasse Skibs løfteanker: (doneCallback) -> console.log "Løfteanker." hvis det er gjortCallback? setTimeout doneCallback, 1000 setVel: (speed) -> console.log "Indstilling af hastighed til # {speed}" sæt sejl: -> @levantarAncla => @fixVel 70 bot = ny Barco bot.zarpar ()
Lad os kompilere vores fil og se hvordan CoffeeScript Præstationsbinding med tyk pilfunktion:

Hvad det gør CoffeeScript før deklareres ring tilbage er at indstille en lokal variabel _Este, som henviser til Este, siden selvom ring tilbage er dynamisk bundet til værdien indlæser stadig den lokale kontekst, hvor den blev erklæret. Endelig skal vi udføre vores genererede fil og derefter se, hvordan fejlen blev løst:

Efter allerede at have set, hvordan man løser kontekstproblemet i vores applikationer med CoffeeScript Vi kommer til at se en temmelig enkel, men kraftfuld teknik til at hjælpe os med at spare arbejde. Det er ikke en avanceret teknik, men det er en logisk måde at foretage en forbedring af vores kode uden store anstrengelser fra vores side.
MemoiseringHvad teknikken til notering er at gemme værdier for en funktion i stedet for at genberegne dem hver gang funktionen kaldes. Nu hvor vi ved, hvordan vi bruger klasser og objekter, kan vi bruge denne viden til at anvende dem inden for CoffeeScript og brug den pågældende teknik.
Der er mange måder at udføre processen på huske, i tilfælde af denne tutorial vil vi holde tingene enkle. Til dette, hvad vi vil gøre, er, at når der anmodes om visse oplysninger, kontrollerer vi, om de er gemt, hvis vi returnerer dem med det samme, ellers kan vi beregne dem og gemme dem til fremtidig brug. Denne teknik er yderst nyttig, når vi skal bruge en kompleks algoritme til at modtage et svar, eller hvis vi bruger et langsomt netværk til at indhente oplysninger.
Så lad os se på koden for at illustrere denne teknik:
 klasse Rocket getPath: -> @path? = @doMathComplexProcess ()
For bedre at forklare denne del af koden vil vi kompilere den for at se hvordan CoffeeScript bygge JavaScript at vores teknik skal spare os for at arbejde i vores udvikling, lad os se, hvordan vores kode ser ud:

FORSTØRRE

Som vi kan se i vores kode, vil beregningen af ​​banen kun blive udført første gang anmodning og den lagrede værdi vil blive brugt fra nu af. Vi kunne også se i vores kode CoffeeScript at vi havde hjælp fra den tertiære operatør ?= som vil evaluere udtrykket i tilfælde af, at stien er nul, derudover vil vi have hjælp fra det implicitte afkast af de funktioner, der vil returnere resultatet af udtrykket, i dette tilfælde værdien af @trajectory om den tidligere er blevet gemt eller netop er beregnet.
Men det er ikke alt, hvad vi kan gøre med vores nye teknik i CoffeeScript, vi kan endda gemme mere end én værdi ved hjælp af en datastruktur, lad os se, hvordan vi kan gøre det:
 klasse SecurityGateway hasAccess: (guard) -> @access? = {} @access [guard.plate_number]? = verifyCredentials guard.plate_number
Hvad denne del af koden gør er, at i vores objekt er resultatet gemt for hver vagt, der har anmodet om adgang, vi ville kun have brug for noget unikt for at kunne identificere dem i vores objekt, så vi bruger tallerkennummeret til denne opgave, lad os se hvordan vores kode oversættes, når vi kompilerer den:

FORSTØRRE

Det er vigtigt at nævne, at denne teknik kun bør bruges med oplysninger, der ikke ændres under udførelsen af ​​vores program, hvis det er tilfældet, anbefaler vi at implementere en løsning baseret på cache.
Endelig vil vi se en måde at videregive muligheder til en funktion, dette er ikke en særlig funktionalitet af CoffeeScriptDet er mere en konvention, der gør brug af mange af sprogets egenskaber ved at bruge dem i et mønster, der er let at forstå, og som er lige så nyttigt i mange situationer, der kan opstå.
Hvordan virker det?Ideen bag dette er enkel, det er at have en funktion, der accepterer dette indstillinger objekt som kan indeholde associerede nøgler til funktionerne. Dette gør indstillingerne lette at forstå ud fra koden, de kaldes i, fordi der er krøllede seler til at identificere, hvad hver værdi gør. Dette reducerer også besværet med at holde øje med argumenterne og deres rækkefølge, da objektnøglerne ikke er afhængige af dette og kan udelades, hvis det ikke er nødvendigt.
At implementere valgmuligheder objekter først vil vi bruge valgfrie argumenter til at standardisere et tomt argument. På denne måde kan vi under opkaldet udelade valgmulighederne, hvis værdierne ikke er nødvendige:
 launchNave = (navn, muligheder = {}) -> returner, hvis optioner. drift tørt starter ()
Nu vil vi bruge den tertiære operatør ?= for at udfylde værdierne for de muligheder, som vi ønsker at have en særlig standardværdi:
 launchNave = (navn, optioner = {}) -> options.count? = 10 console.log "# {i} …" for i i [options.count … 0] returnerer, hvis options.drift tørt starter ()
Vi definerer en sidste værdi, og vi bruger operatoren ? hvis det bruges ét sted:
 launchSave = (navn, optioner = {}) -> checkFuel (options.waitComb? 100) options.count? = 10 console.log "# {i} …" for i i [options.count … 0] returner hvis optioner. tør start ()
Endelig drager vi fordel af den tilladte syntaks for CoffeeScript at sende mulighederne til vores funktion uden parenteserne, hvilket giver os et ret simpelt og naturligt opkald:
 launchShip "Millennium Falcon", DryGear: true, nedtælling: 15
For at afslutte vil vi kompilere vores fil og se output fra vores kode i JavaScript:

FORSTØRRE

Med sidstnævnte sluttede vi denne vejledning, hvor vi ikke kun kunne lære avancerede måder at bruge CoffeeScript men snarere teknikker, der vil hjælpe os med at skrive bedre kode, at vi med konstant brug og forskning kan blive bedre udviklere, der bruger de bedste metoder til at udvikle applikationer.
wave wave wave wave wave