Używam Node.js w pracy i uważam, że jest bardzo wydajny. Zmuszony do wybrania jednego słowa do opisania Node.js, powiedziałbym „interesujący” (co nie jest czysto pozytywnym przymiotnikiem). Społeczność tętni życiem i rośnie. JavaScript, pomimo jego dziwactw, może być świetnym językiem do kodowania. Codziennie będziesz przemyślał własne rozumienie „najlepszych praktyk” i wzorców dobrze ustrukturyzowanego kodu. Node.js napływa teraz ogromna energia pomysłów, a praca w nim naraża cię na całe to myślenie - wielkie mentalne podnoszenie ciężarów.
Produkcja Node.js jest zdecydowanie możliwa, ale daleko od wdrożenia „pod klucz”, które wydaje się obiecane w dokumentacji. W Node.js v0.6.x „klaster” został zintegrowany z platformą, zapewniając jeden z podstawowych elementów składowych, ale mój skrypt „production.js” ma nadal ~ 150 linii logiki do obsługi takich rzeczy, jak tworzenie dziennika katalog, recykling martwych pracowników itp. Aby „poważna” usługa produkcyjna musiała być również przygotowana do ograniczania połączeń przychodzących i robienia wszystkiego, co Apache robi dla PHP . Szczerze mówiąc, Ruby on Rails ma dokładnie ten problem. Rozwiązuje się to za pomocą dwóch uzupełniających się mechanizmów: 1) Umieszczenie Ruby na szynach / węźle.Apache / Lighttd ). Serwer WWW może skutecznie obsługiwać zawartość statyczną, rejestrować dostęp, przepisywać adresy URL, przerywać SSL , egzekwować reguły dostępu i zarządzać wieloma pod-usługami. W przypadku żądań, które trafiły do faktycznej usługi węzła, serwer proxy przekazuje żądanie przez. 2) Używając frameworka takiego jak Unicorn, który będzie zarządzał procesami roboczymi, okresowo je przetwarzał itd. Jeszcze nie znalazłem frameworka obsługującego Node.js, który wydaje się być całkowicie upieczony; może istnieć, ale jeszcze go nie znalazłem i nadal używam ~ 150 wierszy w ręcznie zwiniętym pliku „production.js”.
Czytanie frameworków, takich jak Express , wydaje się, że standardową praktyką jest po prostu obsługiwanie wszystkiego za pośrednictwem jednej usługi Node.js typu jack-of-all-trade ... „app.use (express.static (__ dirname + '/ public'))” . W przypadku usług i rozwoju o niskim obciążeniu prawdopodobnie nie jest to w porządku. Ale gdy tylko spróbujesz obciążyć swoją usługę dużym nakładem czasu i uruchamiać ją 24 godziny na dobę, 7 dni w tygodniu, szybko odkryjesz motywacje, które popychają duże witryny do posiadania dobrze upieczonego, utwardzonego kodu C, takiego jak Nginx, umieszczającego swoją stronę i obsługującego wszystkie żądań zawartości statycznej (... dopóki nie skonfigurujesz sieci CDN , takiej jak Amazon CloudFront )). Dla nieco humorystycznego i bezwstydnie negatywnego podejścia do tego zobacz tego faceta .
Node.js znajduje również coraz więcej zastosowań innych niż usługi. Nawet jeśli używasz czegoś innego do udostępniania treści internetowych, możesz nadal używać Node.js jako narzędzia do kompilacji, używając modułów npm do organizowania kodu, Browserify, aby połączyć go w pojedynczy zasób i uglify-js, aby zminimalizować go do wdrożenia . JavaScript do komunikacji z Internetem jest idealnym dopasowaniem impedancji i często czyni go najłatwiejszą drogą ataku. Na przykład, jeśli chcesz przeszukiwać wiele ładunków odpowiedzi JSON , powinieneś użyć mojego modułu podkreślenia CLI , paska narzędzi danych strukturalnych.
Za I przeciw:
- Pro: Dla serwera, pisanie JavaScript na backendie było „lekiem na bramę” do nauki nowoczesnych wzorców interfejsu użytkownika. Nie boję się już pisania kodu klienta.
- Pro: Zwykle zachęca do prawidłowego sprawdzania błędów (błąd jest zwracany przez praktycznie wszystkie wywołania zwrotne, co utrudnia programistom obsługę; także async.js i inne biblioteki obsługują paradygmat „błąd, jeśli którakolwiek z tych podzadań nie powiedzie się” znacznie lepiej niż typowy kod synchroniczny )
- Pro: Niektóre interesujące i zwykle trudne zadania stają się trywialne - takie jak uzyskanie statusu zadań w locie, komunikacja między pracownikami lub współdzielenie stanu pamięci podręcznej
- Pro: Ogromna społeczność i mnóstwo świetnych bibliotek opartych na solidnym menedżerze pakietów (npm)
- Przeciw: JavaScript nie ma standardowej biblioteki. Tak się przyzwyczajasz do importowania funkcjonalności, że czujesz się dziwnie, gdy używasz JSON.parse lub innej metody wbudowanej, która nie wymaga dodawania modułu npm. Oznacza to, że istnieje pięć wersji wszystkiego. Nawet moduły zawarte w „rdzeniu” Node.js mają pięć dodatkowych wariantów, jeśli nie będziesz zadowolony z domyślnej implementacji. Prowadzi to do szybkiej ewolucji, ale także do pewnego stopnia zamieszania.
W porównaniu z prostym modelem jednoprocesowym na żądanie ( LAMP ):
- Pro: Skalowalny do tysięcy aktywnych połączeń. Bardzo szybki i bardzo wydajny. W przypadku floty internetowej może to oznaczać 10-krotną redukcję wymaganej liczby pudeł w porównaniu z PHP lub Ruby
- Pro: Pisanie równoległych wzorów jest łatwe. Wyobraź sobie, że musisz pobrać trzy (lub N) obiekty BLOB z Memcached . Czy to w PHP ... czy właśnie napisałeś kod, który pobiera pierwszą kroplę, potem drugą, a potem trzecią? Wow, to wolno. Istnieje specjalny moduł PECL do rozwiązania tego konkretnego problemu dla Memcached, ale co zrobić, jeśli chcesz pobrać niektóre Memcached dane równolegle z zapytaniem do bazy danych? W Node.js, ponieważ paradygmat jest asynchroniczny, zlecenie wykonania wielu czynności jednocześnie jest bardzo naturalne.
- Przeciw: kod asynchroniczny jest zasadniczo bardziej złożony niż kod synchroniczny, a krzywa uczenia się z góry może być trudna dla programistów bez dokładnego zrozumienia, co w rzeczywistości oznacza równoczesne wykonywanie. Jest to jednak o wiele mniej trudne niż pisanie kodu wielowątkowego z blokowaniem.
- Przeciw: Jeśli żądanie wymagające dużej mocy obliczeniowej działa na przykład przez 100 ms, zatrzyma przetwarzanie innych żądań, które są obsługiwane w tym samym procesie Node.js ... AKA, wielozadaniowość kooperacyjna . Można to złagodzić za pomocą wzorca Web Workers (wydzielenie podprocesu do wykonania kosztownego zadania). Alternatywnie, możesz użyć dużej liczby pracowników Node.js i pozwolić każdemu z nich obsługiwać tylko jedno żądanie jednocześnie (wciąż dość wydajne, ponieważ nie ma procesu recyklingu).
- Przeciw: Uruchamianie systemu produkcyjnego jest DUŻO bardziej skomplikowane niż model CGI, taki jak Apache + PHP, Perl , Ruby itp. Nieobsługiwane wyjątki obniżą cały proces, wymagając logiki do zrestartowania nieudanych pracowników (patrz klaster ). Moduły z błędnym natywnym kodem mogą spowodować poważne awarie procesu. Za każdym razem, gdy umiera pracownik, wszelkie obsługiwane przez niego żądania są odrzucane, więc jeden błędny interfejs API może łatwo obniżyć jakość usług dla innych interfejsów API współhostowanych.
W przeciwieństwie do pisania „prawdziwej” usługi w Javie / C # / C (C? Naprawdę?)
- Pro: Wykonanie asynchroniczne w Node.js jest łatwiejsze niż zabezpieczenie wątków gdzie indziej i zapewne zapewnia większą korzyść. Node.js jest zdecydowanie najmniej bolesnym paradygmatem asynchronicznym, w jakim kiedykolwiek pracowałem. Przy dobrych bibliotekach jest tylko nieco trudniejszy niż pisanie kodu synchronicznego.
- Pro: Brak błędów wielowątkowości / blokowania. To prawda, że inwestujesz z góry w pisanie bardziej pełnego kodu, który wyraża właściwy asynchroniczny przepływ pracy bez operacji blokowania. I musisz napisać kilka testów i sprawić, by coś zadziałało (jest to język skryptowy, a nazwy zmiennych grubych palców są wychwytywane tylko w czasie testu jednostkowego). ALE, kiedy już uruchomisz, obszar dla heisenbugów - dziwne problemy, które pojawiają się tylko raz na milion przebiegów - ten obszar jest po prostu znacznie mniejszy. Podatki, które piszą kod Node.js, są w dużym stopniu ładowane od początku do fazy kodowania. Potem masz tendencję do uzyskania stabilnego kodu.
- Pro: JavaScript jest znacznie lżejszy do wyrażania funkcjonalności. Trudno to udowodnić słowami, ale JSON , dynamiczne pisanie, notacja lambda, prototypowe dziedziczenie, lekkie moduły, cokolwiek ... po prostu potrzeba mniej kodu, aby wyrazić te same pomysły.
- Przeciw: Może naprawdę lubisz usługi kodowania w Javie?
Aby uzyskać inne spojrzenie na JavaScript i Node.js, sprawdź From Java to Node.js , post na blogu na temat wrażeń i doświadczeń programisty Java na temat uczenia się Node.js.
Moduły
Rozważając węzeł, pamiętaj, że wybór bibliotek JavaScript DEFINICUJE twoje wrażenia. Większość ludzi używa co najmniej dwóch, pomocnika asynchronicznego wzorca (Step, Futures, Async) i modułu cukru JavaScript ( Underscore.js ).
Cukier pomocnika / JavaScript:
- Underscore.js - użyj tego. Po prostu to zrób. Czyni twój kod ładnym i czytelnym dzięki takim rzeczom jak _.isString () i _.isArray (). Nie jestem do końca pewien, jak inaczej napisać bezpieczny kod. Ponadto, aby uzyskać ulepszone wiersze poleceń, sprawdź mój własny interfejs Underscore-CLI .
Moduły wzorców asynchronicznych:
- Krok - bardzo elegancki sposób wyrażania kombinacji działań szeregowych i równoległych. Moje osobiste zalecenie. Zobacz mój post o tym, jak wygląda kod Step.
- Kontrakty terminowe - o wiele bardziej elastyczny (czy to naprawdę dobra rzecz?) Sposób wyrażania zamówienia poprzez wymagania. Potrafi wyrazić takie rzeczy jak: „uruchom a, b, c równolegle. Kiedy A i B zakończą, zacznij AB. Kiedy A i C zakończą, zacznij AC”. Taka elastyczność wymaga większej uwagi, aby uniknąć błędów w przepływie pracy (np. Nigdy nie wywoływać oddzwaniania lub dzwonić wielokrotnie). Zobacz post Raynosa na temat korzystania z futures (jest to post, który sprawił, że „dostałem” futures).
- Asynchronizacja - bardziej tradycyjna biblioteka z jedną metodą dla każdego wzorca. Zacząłem od tego przed moją religijną konwersją na krok i późniejszą świadomością, że wszystkie wzorce w Async można wyrazić na Kroku za pomocą jednego bardziej czytelnego paradygmatu.
- TameJS - napisany przez OKCupid, to prekompilator, który dodaje nową funkcję podstawową języka „czekaj” na eleganckie pisanie szeregowych i równoległych przepływów pracy. Wzór wygląda niesamowicie, ale wymaga wstępnej kompilacji. Nadal zastanawiam się nad tym.
- StreamlineJS - konkurent TameJS. Pochylam się w kierunku Tame, ale możesz podjąć decyzję.
Lub, aby przeczytać wszystko o bibliotekach asynchronicznych, zobacz ten wywiad panelowy z autorami.
Framework sieciowy:
- Ekspresowe środowisko Ruby on Rails-esk do organizowania stron internetowych. Używa JADE jako silnika szablonów XML / HTML, co sprawia, że budowanie HTML jest o wiele mniej bolesne, a nawet eleganckie.
- jQuery Chociaż technicznie nie jest modułem węzła, jQuery szybko staje się de facto standardem dla interfejsu użytkownika po stronie klienta. jQuery zapewnia selektory podobne do CSS do „przeszukiwania” zestawów elementów DOM, na których można następnie operować (programy obsługi, właściwości, style itp.). W tym samym stylu, platforma Bootstrap CSS na Twitterze , Backbone.js dla wzoru MVC i Browserify.js, aby połączyć wszystkie pliki JavaScript w jeden plik. Wszystkie te moduły stają się de facto standardami, więc powinieneś je przynajmniej sprawdzić, jeśli o nich nie słyszałeś.
Testowanie:
- JSHint - Musisz użyć; Na początku nie korzystałem z tego, co teraz wydaje się niezrozumiałe. JSLint dodaje kilka podstawowych weryfikacji uzyskanych za pomocą skompilowanego języka, takiego jak Java. Niedopasowany nawias, niezadeklarowane zmienne, literówki o wielu kształtach i rozmiarach. Możesz także włączyć różne formy tego, co nazywam „trybem analnym”, w którym weryfikujesz styl białych znaków i tak dalej, co jest OK, jeśli to twoja filiżanka herbaty - ale prawdziwa wartość pochodzi z natychmiastowego uzyskiwania informacji zwrotnych na temat dokładnego numeru wiersza, w którym zapomniałeś zamykającego „)” ... bez konieczności uruchamiania kodu i uderzania w linię obrażającą. „JSHint” jest bardziej konfigurowalny wariant Douglas Crockforda „s JSLint .
- Konkurent Mocha do ślubowań, które zaczynam preferować. Oba frameworki radzą sobie z podstawami wystarczająco dobrze, ale złożone wzory są łatwiejsze do wyrażenia w Mokce.
- Ślubowanie Ślubowanie jest naprawdę bardzo eleganckie. I drukuje piękny raport (--spec) pokazujący, które przypadki testowe przeszły / nie powiodły się. Poświęć 30 minut na naukę, a przy minimalnym wysiłku możesz stworzyć podstawowe testy modułów.
- Zombie - Bezgłowe testowanie HTML i JavaScript za pomocą JSDom jako wirtualnej „przeglądarki”. Bardzo potężne rzeczy. Połącz go z Replay, aby uzyskać błyskawiczne, deterministyczne testy kodu w przeglądarce.
- Komentarz na temat tego, jak „pomyśleć o” testowaniu:
- Testowanie nie jest opcjonalne. W przypadku dynamicznego języka, takiego jak JavaScript, jest bardzo mało sprawdzeń statycznych. Na przykład przekazanie dwóch parametrów do metody, która oczekuje 4, nie ulegnie awarii, dopóki kod nie zostanie wykonany. Dość niski pasek do tworzenia błędów w JavaScript. Podstawowe testy są niezbędne do uzupełnienia luki weryfikacyjnej w skompilowanych językach.
- Zapomnij o sprawdzeniu poprawności, po prostu uruchom kod. Dla każdej metody moim pierwszym przypadkiem sprawdzania poprawności jest „nic się nie psuje”, i to jest przypadek, który najczęściej się uruchamia. Udowodnienie, że Twój kod działa bez rzucania, wyłapuje 80% błędów i zrobi tak wiele, aby zwiększyć pewność kodu, że cofniesz się i dodasz niuansowe przypadki sprawdzania poprawności, które pominęłeś.
- Zacznij od małego i przełam barierę bezwładności. Wszyscy jesteśmy leniwi i potrzebujemy czasu, a testowanie można łatwo uznać za „dodatkową pracę”. Więc zacznij od małej. Napisz przypadek testowy 0 - załaduj moduł i zgłoś sukces. Jeśli zmusisz się do zrobienia właśnie tyle, wtedy bariera bezwładności w testowaniu zostanie przełamana. To mniej niż 30 minut na zrobienie tego za pierwszym razem, łącznie z przeczytaniem dokumentacji. Teraz napisz przypadek testowy 1 - wywołaj jedną ze swoich metod i sprawdź, czy „nic się nie psuje”, to znaczy, że nie otrzymasz z powrotem błędu. Przypadek testowy 1 powinien zająć Ci mniej niż minutę. Po zniknięciu bezwładności łatwo jest stopniowo zwiększać zasięg testu.
- Teraz rozwijaj swoje testy za pomocą kodu. Nie daj się zastraszyć, jak wyglądałby „prawidłowy” kompleksowy test z fałszywymi serwerami i tym podobne. Kod zaczyna się od prostej i ewoluuje, aby obsługiwać nowe przypadki; testy też powinny. Gdy dodajesz nowe przypadki i nową złożoność do swojego kodu, dodaj przypadki testowe, aby wykonać nowy kod. Gdy znajdziesz błędy, dodaj weryfikacje i / lub nowe przypadki, aby zakryć wadliwy kod. Kiedy debugujesz i tracisz zaufanie do fragmentu kodu, wróć i dodaj testy, aby udowodnić, że robi to, co myślisz. Przechwytuj ciągi przykładowych danych (z innych usług, do których dzwonisz, zeskrobywanych witryn, cokolwiek) i przesyłaj je do swojego kodu parsującego. Kilka przypadków tutaj, poprawione sprawdzanie poprawności, a skończysz z wysoce niezawodnym kodem.
Sprawdź także oficjalną listę zalecanych modułów Node.js. Jednak Wiki Node Modules GitHub jest znacznie bardziej kompletna i stanowi dobry zasób.
Aby zrozumieć Węzeł, warto rozważyć kilka kluczowych opcji projektowania:
Node.js jest OPARTY NA ZDARZENIACH i ASYNCHRONICZNY / NIE BLOKUJĄCY. Zdarzenia, takie jak przychodzące połączenie HTTP, uruchamiają funkcję JavaScript, która wykonuje trochę pracy i uruchamia inne asynchroniczne zadania, takie jak łączenie się z bazą danych lub pobieranie zawartości z innego serwera. Po uruchomieniu tych zadań funkcja zdarzenia kończy się, a Node.js wraca do trybu uśpienia. Gdy tylko wydarzy się coś innego, na przykład nawiązywane połączenie z bazą danych lub serwer zewnętrzny odpowiadający treścią, uruchamiane są funkcje wywołania zwrotnego i wykonuje się więcej kodu JavaScript, potencjalnie uruchamiając jeszcze więcej zadań asynchronicznych (takich jak zapytanie do bazy danych). W ten sposób Node.js z radością przeplata działania dla wielu równoległych przepływów pracy, uruchamiając wszelkie działania, które są odblokowane w dowolnym momencie. Dlatego Node.js wykonuje tak świetną robotę, zarządzając tysiącami jednoczesnych połączeń.
Dlaczego nie użyć jednego procesu / wątku na połączenie, jak wszyscy inni?W Node.js nowe połączenie jest tylko bardzo małą alokacją sterty. Przyspieszenie nowego procesu wymaga znacznie więcej pamięci, megabajt na niektórych platformach. Ale rzeczywisty koszt to narzut związany z przełączaniem kontekstu. Kiedy masz 10 ^ 6 wątków jądra, jądro musi wykonać wiele pracy, zastanawiając się, kto powinien wykonać następny. Sporo pracy poświęcono na zbudowanie harmonogramu O (1) dla Linuksa, ale ostatecznie o wiele bardziej efektywne jest posiadanie jednego procesu sterowanego zdarzeniem niż 10 ^ 6 procesów rywalizujących o czas procesora. Ponadto, w warunkach przeciążenia, model wieloprocesowy zachowuje się bardzo słabo, głodując krytyczne usługi administracji i zarządzania, szczególnie SSHD (co oznacza, że nie możesz nawet zalogować się do skrzynki, aby dowiedzieć się, jak naprawdę jest przykręcony).
Node.js jest POJEDYNCZY GWINTOWANY i BEZPŁATNY . Node.js, jako bardzo przemyślany wybór projektu, ma tylko jeden wątek na proces. Z tego powodu dostęp do danych jednocześnie przez wiele wątków jest zasadniczo niemożliwy. Dlatego nie są potrzebne żadne blokady. Wątki są trudne. Naprawdę bardzo ciężko. Jeśli w to nie wierzysz, nie wykonałeś wystarczająco dużo programowania wątkowego. Prawidłowe zablokowanie jest trudne i powoduje błędy, które są naprawdę trudne do wyśledzenia. Wyeliminowanie blokad i wielowątkowości sprawia, że jedna z najgorszych klas błędów po prostu odchodzi. To może być największa zaleta węzła.
Ale jak mogę skorzystać z mojego 16-rdzeniowego urządzenia?
Dwie drogi:
- W przypadku dużych zadań obliczeniowych, takich jak kodowanie obrazu, Node.js może odpalać procesy potomne lub wysyłać wiadomości do dodatkowych procesów roboczych. W tym projekcie miałbyś jeden wątek zarządzający przepływem zdarzeń i procesami N wykonującymi ciężkie zadania obliczeniowe i przełamującymi pozostałe 15 procesorów.
- Aby skalować przepustowość w usłudze sieciowej, powinieneś uruchomić wiele serwerów Node.js na jednym urządzeniu, po jednym na rdzeń, używając klastra (w Node.js v0.6.x, oficjalny moduł „klastra”, który jest tutaj powiązany, zastępuje wersję learnboost, która ma inny interfejs API). Te lokalne serwery Node.js mogą następnie konkurować w gnieździe o akceptację nowych połączeń, równoważąc obciążenie między nimi. Po zaakceptowaniu połączenia zostaje ono ściśle powiązane z jednym z tych współużytkowanych procesów. Teoretycznie brzmi to źle, ale w praktyce działa całkiem dobrze i pozwala uniknąć kłopotów z pisaniem bezpiecznego kodu. Oznacza to również, że Node.js uzyskuje doskonałe powinowactwo do pamięci podręcznej procesora, efektywniej wykorzystując przepustowość pamięci.
Node.js pozwala robić naprawdę potężne rzeczy bez zerwania. Załóżmy, że masz program Node.js, który wykonuje różne zadania, nasłuchujepoleceń na porcie TCP i koduje niektóre obrazy. Za pomocą pięciu wierszy kodu możesz dodać portal zarządzania oparty na HTTP, który pokazuje aktualny stan aktywnych zadań. ŁATWO jest zrobić:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(myJavascriptObject.getSomeStatusInfo());
}).listen(1337, "127.0.0.1");
Teraz możesz kliknąć adres URL i sprawdzić status swojego uruchomionego procesu. Dodaj kilka przycisków, a otrzymasz „portal zarządzania”. Jeśli masz działający skrypt Perl / Python / Ruby, samo „wrzucenie portalu zarządzania” nie jest do końca proste.
Ale czy JavaScript nie jest wolny / zły / zły / spawn-of-the-devil? JavaScript ma pewne dziwne dziwactwa, ale z „dobrymi stronami” jest tam bardzo mocny język, aw każdym razie JavaScript jest językiem na kliencie (przeglądarce). JavaScript zostanie tutaj; inne języki celują w to jako IL, a światowej klasy talent konkuruje o produkcję najbardziej zaawansowanych silników JavaScript. Ze względu na rolę JavaScriptu w przeglądarce włożono ogromny wysiłek inżynieryjny w szybkie przyspieszenie JavaScript. V8to najnowszy i największy silnik javascript, przynajmniej na ten miesiąc. Zdmuchuje inne języki skryptowe zarówno pod względem wydajności ORAZ stabilności (patrząc na ciebie, Ruby). I tylko poprawi się to dzięki ogromnym zespołom pracującym nad tym problemem w Microsoft, Google i Mozilli, konkurujących o zbudowanie najlepszego silnika JavaScript (To już nie jest „interpreter” JavaScript, ponieważ wszystkie nowoczesne silniki robią mnóstwo JITkompilacja pod maską z interpretacją tylko jako rezerwowy kod dla kodu jednorazowego wykonania). Tak, wszyscy chcielibyśmy naprawić kilka dziwniejszych wyborów językowych JavaScript, ale tak naprawdę nie jest tak źle. A język jest tak elastyczny, że tak naprawdę nie kodujesz JavaScript, kodujesz Step lub jQuery - bardziej niż jakikolwiek inny język, w JavaScript biblioteki definiują to doświadczenie. Aby budować aplikacje internetowe, i tak musisz znać JavaScript, więc kodowanie go na serwerze ma pewnego rodzaju synergię umiejętności. Sprawiło, że nie boję się pisać kodu klienta.
Poza tym, jeśli NAPRAWDĘ nienawidzisz JavaScript, możesz użyć cukru syntaktycznego, takiego jak CoffeeScript . Lub cokolwiek innego, co tworzy kod JavaScript, na przykład Google Web Toolkit (GWT).
Mówiąc o JavaScript, co to jest „zamknięcie”? - Właściwie fantazyjny sposób powiedzenia, że zachowuje się zmienne o zasięgu leksykalnym w łańcuchach połączeń. ;) Lubię to:
var myData = "foo";
database.connect( 'user:pass', function myCallback( result ) {
database.query("SELECT * from Foo where id = " + myData);
} );
// Note that doSomethingElse() executes _BEFORE_ "database.query" which is inside a callback
doSomethingElse();
Widzisz, jak możesz po prostu użyć „myData” bez robienia czegokolwiek niewygodnego, jak wbicie go do obiektu? I inaczej niż w Javie, zmienna „myData” nie musi być tylko do odczytu. Ta potężna funkcja języka sprawia, że programowanie asynchroniczne jest znacznie mniej szczegółowe i mniej bolesne.
Pisanie kodu asynchronicznego zawsze będzie bardziej skomplikowane niż pisanie prostego skryptu jednowątkowego, ale w Node.js nie jest to dużo trudniejsze i zyskujesz wiele korzyści oprócz wydajności i skalowalności dla tysięcy jednoczesnych połączeń. ..