Zaawansowane wykorzystanie CoffeeScript

Spisie treści
W poprzednich samouczkach pracowaliśmy z klasami, dzięki czemu nasza aplikacja była bardziej modułowa, widzieliśmy nawet dogłębnie, jak wykonywać pracę asynchroniczną za pomocą CoffeeScript jako język, co daje nam więcej możliwości pracy z nim.
Po opanowaniu tych koncepcji nadszedł czas, aby pójść o krok dalej i wykorzystać to, co wiemy, do napisania czystszego, bardziej funkcjonalnego i oczywiście potężniejszego kodu. Czas nauczyć się, jak zostać zaawansowanymi użytkownikami CoffeeScript.
Skoro już wiemy, jak korzystać z klas w naszej aplikacji, to tylko kwestia czasu, zanim pojawią się z tym problemy. kontekst. Kiedy jesteśmy z prostymi funkcjami, dość łatwo jest zobaczyć, jakie dane ta funkcja ma w swoim zakresie, zna zmienne globalne, zmienne zdefiniowane w ramach funkcji i każdą zmienną, która została zdefiniowana w zakresie lokalnym podczas tworzenia funkcji.
Ale kiedy metody są powiązane z obiektami, staje się to nieco bardziej skomplikowane. Aby to zilustrować, spójrzmy na przykład, na którym widzimy ten problem, a potem zobaczymy jak CoffeeScript może nam pomóc:
 class Kotwica do podnoszenia statku: (doneCallback) -> console.log "Podnoszenie kotwicy". setVel: (speed) -> console.log "Ustawienie prędkości na # {speed}" ustaw żagiel: -> @levantarAncla @ fixVel 70
Załóżmy więc, zgodnie z naszym kodem, że chcemy natychmiast wypłynąć, w tym celu wykonujemy następujące czynności, aby wywołać naszą funkcję:
 bot = nowy Barco bot.zarpar ()
Jeśli przyjrzymy się uważnie i przeniesiemy ten kod do realnego świata, zdamy sobie sprawę, że podniesienie kotwicy nie następuje od razu, musimy poczekać, aż kotwica zostanie w pełni podniesiona, aby móc postawić żagiel. Możemy rozwiązać ten problem, dodając a oddzwonić i pytamy czy została zakończona, abyśmy wiedzieli jak długo trwa ta akcja i po zakończeniu wywołamy naszą funkcję, zobaczmy:
 liftAnchor: (doneCallback) -> console.log "Podnoszenie kotwicy." jeśli zrobioneOddzwoń? setTimeout doneOddzwoń, 1000
Jak widać, wywołujemy callback tylko, jeśli istnieje, w ten sposób upewniamy się, że ten proces został zakończony i dlatego musimy zmodyfikować naszą funkcję odpłynąć:
 wypłyń: -> @levantarAncla -> @ fixVel 70
Teraz wywołujemy funkcję odpłynąć Po podniesieniu kotwicy gwarantuje to, że nie ruszymy się, dopóki kotwica nie zostanie w pełni podniesiona. Wygląda to całkiem nieźle, zamierzamy skompilować nasz kod i dołączyć wygenerowany plik .js do kodu HTML, aby zobaczyć odpowiedź w konsoli:

Jak widać na obrazku otrzymaliśmy błąd, w którym mówi, że funkcja nie istnieje. Co się stało? To bardzo proste, JavaScript ustawił wartość Este w sposób, w jaki funkcja została wywołana, od momentu wywołania bot.zarpar wartość Este jest powiązany z obiektem nerw, więc jest to związane z kontekstem globalnym i nie o to nam chodzi.
Chcemy się upewnić, że Este jest zawsze powiązany z instancją nerw w treści wywołania zwrotnego i mamy szczęście, ponieważ CoffeeScript ma funkcję dla tego przypadku. W tym celu zadeklarujemy funkcję z gruba strzała lub grubą strzałkę, w ten sposób funkcja będzie miała Este powiązany z kontekstem, w którym został zadeklarowany, zobaczmy jak wygląda nasz kod z tą zmianą:
 class Kotwica do podnoszenia statku: (doneCallback) -> console.log "Podnoszenie kotwicy". jeśli zrobioneOddzwoń? setTimeout doneCallback, 1000 setVel: (speed) -> console.log "Ustawianie prędkości na # {speed}" ustaw żagiel: -> @levantarAncla => @fixVel 70 bot = new Barco bot.zarpar ()
Skompilujmy nasz plik i zobaczmy jak CoffeeScript Powiązanie osiągnięć z funkcją grubej strzałki:

Co to robi CoffeeScript przed zadeklarowaniem oddzwonić jest ustawienie zmiennej lokalnej _Este, który odnosi się do Este, ponieważ chociaż oddzwonić jest dynamicznie powiązany z wartością, nadal ładuje kontekst lokalny, w którym został zadeklarowany. Na koniec wykonamy nasz wygenerowany plik, a następnie zobaczymy, jak błąd został rozwiązany:

Widząc już, jak rozwiązać problem kontekstowy w naszych aplikacjach za pomocą CoffeeScript Zobaczymy dość prostą, ale potężną technikę, która pomoże nam zaoszczędzić pracę. Nie jest to zaawansowana technika, ale logiczny sposób na ulepszenie naszego kodu bez większego wysiłku z naszej strony.
ZapamiętywanieJaka jest technika zapamiętywanie jest przechowywanie wartości funkcji zamiast przeliczania ich przy każdym wywołaniu funkcji. Teraz, gdy wiemy, jak korzystać z klas i obiektów, możemy wykorzystać tę wiedzę, aby zastosować je wewnątrz CoffeeScript i użyj danej techniki.
Istnieje wiele sposobów na przeprowadzenie procesu zapamiętywanie, w przypadku tego samouczka zachowamy prostotę. W tym celu zrobimy, że gdy zażądamy pewnych informacji, zweryfikujemy, czy są one przechowywane, a jeśli tak, zwrócimy je natychmiast, w przeciwnym razie możemy je obliczyć i zapisać do wykorzystania w przyszłości. Ta technika jest niezwykle przydatna, gdy potrzebujemy użyć złożonego algorytmu, aby otrzymać odpowiedź lub w przypadku, gdy używamy powolnej sieci do uzyskania informacji.
Spójrzmy więc na kod, aby zilustrować tę technikę:
 class Rocket getPath: -> @path?= @doMathComplexProcess ()
Aby lepiej wyjaśnić tę część kodu, skompilujemy ją, aby zobaczyć, jak CoffeeScript zbuduj JavaScript że nasza technika będzie musiała zaoszczędzić nam pracy w rozwoju, zobaczmy jak wygląda nasz kod:

POWIĘKSZAĆ

Jak widać w naszym kodzie, obliczenie trajektorii zostanie przeprowadzone dopiero za pierwszym razem żądanie a przechowywana wartość będzie używana od teraz. Mogliśmy też zobaczyć w naszym kodzie CoffeeScript że mieliśmy pomoc trzeciorzędnego operatora ?= która oceni wyrażenie w przypadku, gdy ścieżka jest pusta, dodatkowo będziemy mieli pomoc w postaci niejawnego zwrotu funkcji, które zwrócą wynik wyrażenia, w tym przypadku wartość @trajektoria niezależnie od tego, czy został wcześniej zapisany, czy właśnie został obliczony.
Ale to nie wszystko, co możemy zrobić z naszą nową techniką w CoffeeScript, możemy nawet przechowywać więcej niż jedną wartość za pomocą struktury danych, zobaczmy, jak możemy to zrobić:
 class SecurityGateway hasAccess: (guard) -> @access?= {} @access [guard.plate_number]?= VerifyCredentials guard.plate_number
To, co robi ta część kodu, polega na tym, że w naszym obiekcie wynik jest przechowywany dla każdego strażnika, który zażądał dostępu, potrzebowalibyśmy tylko czegoś unikalnego, aby móc zidentyfikować go w naszym obiekcie, więc używamy numeru rejestracyjnego do tego zadania, zobaczmy jak nasz kod jest tłumaczony, gdy go kompilujemy:

POWIĘKSZAĆ

Należy wspomnieć, że technika ta powinna być stosowana tylko z informacjami, które nie ulegną zmianie podczas wykonywania naszego programu, w przypadku gdy tak jest, zalecamy wdrożenie rozwiązania opartego na Pamięć podręczna.
Na koniec zobaczymy sposób przekazywania opcji do funkcji, nie jest to specjalna funkcjonalność CoffeeScriptJest to raczej konwencja, która wykorzystuje wiele cech języka, używając ich w sposób łatwy do zrozumienia i równie przydatny w wielu sytuacjach, które mogą się pojawić.
Jak to działa?Idea, która się za tym kryje, jest prosta, polega na posiadaniu funkcji, która to akceptuje obiekt opcji które mogą zawierać klucze asocjacyjne dla argumentów tej funkcji. Dzięki temu opcje są łatwe do zrozumienia z kodu, w którym są wywoływane, ponieważ istnieją nawiasy klamrowe, które identyfikują, co robi każda wartość. Zmniejsza to również kłopoty z pilnowaniem argumentów, a także ich kolejnością, ponieważ klucze obiektów nie są od tego zależne i można je pominąć, jeśli nie są potrzebne.
Aby wdrożyć obiekty opcji najpierw użyjemy opcjonalnych argumentów, aby domyślnie był pustym argumentem. W ten sposób przy wywołaniu możemy pominąć opcje w przypadku, gdy wartości nie są potrzebne:
 launchNave = (nazwa, opcje = {}) -> powrót, jeśli options.drift suchy start ()
Teraz użyjemy operatora trzeciorzędnego ?= uzupełnić wartości opcji, które chcemy mieć specjalną wartość domyślną:
 launchNave = (name, options = {}) -> options.count? = 10 console.log "# {i}…" for i in [options.count… 0] return if options.drift suchy start ()
Definiujemy ostatnią wartość i używamy operatora ? w przypadku użycia w jednym miejscu:
 launchSave = (name, options = {}) -> checkFuel (options.waitComb? 100) options.count? = 10 console.log "# {i}…" dla i w [options.count… 0] return if options. suchy start ()
Wreszcie korzystamy z permisywnej składni CoffeeScript aby wysłać opcje do naszej funkcji bez nawiasów, co daje nam całkiem proste i naturalne wywołanie:
 launchShip „Millennium Falcon”, DryGear: prawda, odliczanie: 15
Na koniec skompilujemy nasz plik i zobaczymy wynik naszego kodu w JavaScript:

POWIĘKSZAĆ

Z tym ostatnim zakończyliśmy ten samouczek, w którym mogliśmy nauczyć się nie tylko zaawansowanych sposobów użytkowania CoffeeScript ale raczej techniki, które pomogą nam pisać lepszy kod, które dzięki ciągłemu użyciu i badaniom możemy stać się lepszymi programistami, korzystającymi z najlepszych praktyk tworzenia aplikacji.

Będziesz pomóc w rozwoju serwisu, dzieląc stronę ze swoimi znajomymi

wave wave wave wave wave