Czytałem nodebeginner I natknąłem się na następujące dwa fragmenty kodu.
Pierwszy:
var result = database.query("SELECT * FROM hugetable");
console.log("Hello World");
Drugie:
database.query("SELECT * FROM hugetable", function(rows) {
var result = rows;
});
console.log("Hello World");
Rozumiem, co powinni zrobić, przeszukują bazę danych, aby uzyskać odpowiedź na zapytanie. A potem console.log('Hello world')
.
Pierwszy to rzekomo kod synchroniczny. A drugi to kod asynchroniczny.
Różnica między tymi dwoma kawałkami jest dla mnie bardzo niejasna. Jaki byłby wynik?
Googling w programowaniu asynchronicznym też mi nie pomógł.
database.query()
, to powinienem wywołać je synchronicznie, prawda? lub jakie powinno być podejście? (To pytanie mam od dawna)Odpowiedzi:
Różnica polega na tym, że w pierwszym przykładzie program zablokuje się w pierwszym wierszu. Następna linia (
console.log
) będzie musiała poczekać.w drugim przykładzie The
console.log
będzie wykonane podczas zapytanie jest przetwarzany. Oznacza to, że zapytanie zostanie przetworzone w tle, podczas gdy twój program będzie robił inne rzeczy, a gdy dane zapytania będą gotowe, zrobisz z nim, co chcesz.Krótko mówiąc: pierwszy przykład zostanie zablokowany, a drugi nie.
Dane wyjściowe następujących dwóch przykładów:
Byłoby:
Query finished
Next line
Next line
Query finished
Uwaga
Chociaż sam węzeł jest jednowątkowy , istnieje kilka zadań, które można uruchomić równolegle. Na przykład operacje systemu plików występują w innym procesie.
Dlatego Node może wykonywać operacje asynchroniczne: jeden wątek wykonuje operacje na systemie plików, podczas gdy główny wątek Node wykonuje kod javascript. Na serwerze sterowanym zdarzeniami, takim jak Węzeł, wątek systemu plików powiadamia główny wątek węzła o określonych zdarzeniach, takich jak zakończenie, niepowodzenie lub postęp, wraz z wszelkimi danymi powiązanymi z tym zdarzeniem (np. Wynikiem zapytania do bazy danych lub błędu wiadomość), a główny wątek węzła decyduje, co zrobić z tymi danymi.
Więcej na ten temat możesz przeczytać tutaj: Jak działa jednowątkowy nieblokujący model IO w Node.js
źródło
request query.; 5 seconds later when the request is done; console.log
:; gdy drugie wykonywane jednokrotnie:request query; console.log; work on the query
;database.query
kończy się tak szybko, że zanim dotrzemyconsole.log
zadanie jest już wykonane.console.log("Next line");
w przykładzie 2 znajdował się w funkcji anonimowej, więc zaraz potemconsole.log("query finished");
oznaczałoby to, że „Następna linia” zostanie wydrukowana PO zakończeniu zapytania, prawda? Więc jeśli mam wszystko w sposób zagnieżdżony, wszystko działałoby w sposób synchroniczny, więc nie musiałbym się martwić o używanie synchronicznych wersji niektórych funkcji. Czy mam rację w moim rozumieniu?Różnica między tymi dwoma podejściami jest następująca:
Sposób synchroniczny: czeka na zakończenie każdej operacji, po czym wykonuje tylko następną operację. W przypadku zapytania:
console.log()
polecenie nie zostanie wykonane, dopóki zapytanie nie zakończy się, aby uzyskać wszystkie wyniki z bazy danych.Sposób asynchroniczny: nigdy nie czeka na zakończenie każdej operacji, raczej wykonuje wszystkie operacje tylko w pierwszym GO. Wynik każdej operacji zostanie obsłużony, gdy wynik będzie dostępny. W przypadku zapytania:
console.log()
polecenie zostanie wykonane wkrótce poDatabase.Query()
metodzie. Podczas gdy zapytanie do bazy danych działa w tle i ładuje wynik po zakończeniu pobierania danych.Przypadków użycia
Jeśli twoje operacje nie wykonują bardzo ciężkich operacji podnoszenia, takich jak wysyłanie zapytań do ogromnych danych z DB, postępuj zgodnie z metodą Synchroniczną, inaczej Asynchroniczną.
W sposób asynchroniczny możesz pokazać użytkownikowi wskaźnik postępu, a w tle możesz kontynuować ciężką pracę. Jest to idealny scenariusz dla aplikacji GUI.
źródło
console.log
?Stałoby się to nieco wyraźniejsze, jeśli dodasz wiersz do obu przykładów:
Drugie:
Spróbuj uruchomić je, a zauważysz, że pierwszy (synchroniczny) przykład, wynik. Długość zostanie wydrukowany PRZED linią „Hello World”. W drugim (asynchronicznym) przykładzie wynik. Długość zostanie (najprawdopodobniej) wydrukowany PO wierszu „Hello World”.
Dzieje się tak, ponieważ w drugim przykładzie
database.query
jest on uruchamiany asynchronicznie w tle, a skrypt jest kontynuowany od razu z „Hello World”.console.log(result.length)
Jest wykonywana tylko wtedy, gdy zapytanie do bazy danych została zakończona.źródło
Po pierwsze, zdaję sobie sprawę, że spóźniłem się z odpowiedzią na to pytanie.
Zanim omówimy synchroniczne i asynchroniczne, przyjrzyjmy się pokrótce, jak działają programy.
W przypadku synchronicznym każda instrukcja kończy się przed uruchomieniem następnej instrukcji. W takim przypadku program jest oceniany dokładnie w kolejności instrukcji.
Tak działa asynchroniczny w JavaScript. Mechanizm JavaScript składa się z dwóch części, z których jedna przegląda kod i kolejkuje operacje, a druga przetwarza kolejkę. Przetwarzanie kolejki odbywa się w jednym wątku, dlatego jednocześnie może wystąpić tylko jedna operacja.
Gdy widoczna jest operacja asynchroniczna (jak drugie zapytanie bazy danych), kod jest analizowany, a operacja umieszczana w kolejce, ale w tym przypadku rejestrowane jest wywołanie zwrotne do uruchomienia po zakończeniu tej operacji. W kolejce może być już wiele operacji. Operacja z przodu kolejki jest przetwarzana i usuwana z kolejki. Po przetworzeniu operacji na zapytanie do bazy danych żądanie jest wysyłane do bazy danych, a po zakończeniu wywołanie zwrotne zostanie wykonane po zakończeniu. W tej chwili procesor kolejek, który „obsłużył” operację, przechodzi do następnej operacji - w tym przypadku
Zapytanie do bazy danych jest nadal przetwarzane, ale operacja console.log znajduje się z przodu kolejki i jest przetwarzana. Ta operacja synchroniczna jest wykonywana natychmiast, co powoduje natychmiastowe wyświetlenie wyniku „Hello World”. Jakiś czas później operacja bazy danych jest zakończona, dopiero wtedy wywołanie zwrotne zarejestrowane w zapytaniu jest wywoływane i przetwarzane, ustawiając wartość wyniku zmiennej na wiersze.
Możliwe, że jedna operacja asynchroniczna spowoduje kolejną operację asynchroniczną, ta druga operacja zostanie umieszczona w kolejce, a jeśli dojdzie do przodu kolejki, zostanie przetworzona. Wywołanie wywołania zwrotnego zarejestrowanego w operacji asynchronicznej jest sposobem, w jaki czas działania JavaScript zwraca wynik operacji po jej zakończeniu.
Prostą metodą sprawdzenia, która operacja JavaScript jest asynchroniczna, jest zwrócenie uwagi, czy wymaga ona wywołania zwrotnego - wywołanie zwrotne to kod, który zostanie wykonany po zakończeniu pierwszej operacji. W dwóch przykładach w pytaniu widzimy, że tylko drugi przypadek ma wywołanie zwrotne, więc jest to asynchroniczna operacja dwóch. Nie zawsze tak jest z powodu różnych stylów obsługi wyniku operacji asynchronicznej.
Aby dowiedzieć się więcej, przeczytaj o obietnicach. Obietnice to kolejny sposób, w jaki można obsłużyć wynik operacji asynchronicznej. Zaletą obietnic jest to, że styl kodowania przypomina bardziej kod synchroniczny.
Wiele bibliotek, takich jak węzeł „fs”, udostępnia style synchroniczne i asynchroniczne dla niektórych operacji. W przypadkach, gdy operacja nie trwa długo i nie jest często używana - jak w przypadku odczytu pliku konfiguracyjnego - operacja synchroniczna spowoduje, że kod będzie łatwiejszy do odczytania.
źródło
W przypadku synchronicznym polecenie console.log nie jest wykonywane, dopóki zapytanie SQL nie zakończy się.
W przypadku asynchronicznym polecenie console.log zostanie wykonane bezpośrednio. Wynik zapytania zostanie następnie zapisany przez funkcję „oddzwaniania”.
źródło
Główna różnica polega na programowaniu asynchronicznym, w przeciwnym razie nie można zatrzymać wykonywania. Możesz kontynuować wykonywanie innego kodu podczas tworzenia „żądania”.
źródło
Ta funkcja sprawia, że druga jest asynchroniczna.
Pierwszy zmusza program do czekania, aż każda linia zakończy działanie, zanim następny będzie mógł kontynuować. Drugi pozwala każdej linii biegać jednocześnie (i niezależnie) jednocześnie.
Języki i frameworki (js, node.js), które pozwalają na asynchronię lub współbieżność, świetnie nadają się do rzeczy wymagających transmisji w czasie rzeczywistym (np. Czat, aplikacje giełdowe).
źródło
Programowanie synchroniczne
Języki programowania, takie jak C, C #, Java są programowaniem synchronicznym, wszystko, co piszesz, będzie wykonywane w kolejności pisania.
Asynchronizacja
NodeJs ma funkcję asynchroniczną, nie ma charakteru blokowania, załóżmy, że w każdym zadaniu we / wy, które wymaga czasu (pobieranie, pisanie, czytanie), nodejs nie będzie bezczynny i nie będzie czekał na zakończenie zadania, to „ Zacznę wykonywać kolejne zadania w kolejce i za każdym razem, gdy podejmowanie zadania zakończy się, powiadomi za pomocą wywołania zwrotnego. Poniższy przykład pomoże:
Krótko mówiąc, wynik jest następujący:
Różnica jest oczywista, gdzie synchronizacja z pewnością zajmie więcej niż 600 (500 + 100 + czas przetwarzania) ms, asynchronia oszczędza czas.
źródło
Funkcje synchroniczne blokują, a funkcje asynchroniczne nie. W funkcjach synchronicznych instrukcje kończą się przed uruchomieniem następnej instrukcji. W takim przypadku program jest oceniany dokładnie w kolejności instrukcji, a wykonywanie programu jest wstrzymywane, jeśli jedna z instrukcji zajmuje bardzo dużo czasu.
Funkcje asynchroniczne zwykle akceptują wywołanie zwrotne jako parametr i wykonywanie jest kontynuowane w następnym wierszu natychmiast po wywołaniu funkcji asynchronicznej. Wywołanie zwrotne jest wywoływane tylko wtedy, gdy operacja asynchroniczna jest zakończona, a stos wywołań jest pusty. Intensywne operacje, takie jak ładowanie danych z serwera WWW lub wyszukiwanie w bazie danych, powinny być wykonywane asynchronicznie, aby główny wątek mógł kontynuować wykonywanie innych operacji zamiast blokować do czasu zakończenia tej długiej operacji (w przypadku przeglądarek interfejs użytkownika zawiesza się) .
Orginal Wysłany na Github: Link
źródło
Programowanie asynchroniczne w JS:
Synchroniczny
Asynchroniczny
Przykład:
źródło