Jaka jest różnica między programowaniem synchronicznym a asynchronicznym (w node.js)

Czytam nodebeginner I natknąłem się na następujące dwa kawałki kodu.

Pierwszy:

    var result = database.query("SELECT * FROM hugetable");
    console.log("Hello World");

Drugi:

    database.query("SELECT * FROM hugetable", function(rows) {
       var result = rows;
    });
    console.log("Hello World");

Rozumiem, co mają zrobić, odpytują bazę danych, aby uzyskać odpowiedź na zapytanie. A potem console.log('Hello world').

Pierwszy to rzekomo synchroniczny kod. A drugi to kod asynchroniczny.

Różnica między tymi dwoma częściami jest dla mnie bardzo niejasna. Jaki wynik być? Googlowanie programowania asynchronicznego też mi nie pomogło.
Author: saji89, 2013-05-02

8 answers

Różnica polega na tym, że w pierwszym przykładzie program zablokuje pierwszą linię. Następna linia (console.log) będzie musiała poczekać.

W drugim przykładzie , console.log zostanie wykonane podczas przetwarzania zapytania. Oznacza to, że zapytanie będzie przetwarzane w tle, podczas gdy twój program robi inne rzeczy, a gdy dane zapytania są gotowe, zrobisz z nim wszystko, co chcesz.

Więc w skrócie: pierwszy przykład zablokuje, podczas gdy drugi nie będzie.

Wyjście z następujących dwóch przykładów:

// Example 1 - Synchronous (blocks)
var result = database.query("SELECT * FROM hugetable");
console.log("Query finished");
console.log("Next line");


// Example 2 - Asynchronous (doesn't block) 
database.query("SELECT * FROM hugetable", function(result) {
    console.log("Query finished");
});
console.log("Next line");

Byłoby:

  1. Query finished
    Next line
  2. Next line
    Query finished

Uwaga
Chociaż sam węzeł jest z pojedynczym wątkiem , istnieją pewne zadania, które mogą działać 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 systemu plików, podczas gdy główny wątek węzła wykonuje kod javascript. W przypadku serwera sterowanego zdarzeniami, takiego jak Node, wątek systemu plików powiadamia główny wątek węzła o pewnych zdarzeniach, takich jak zakończenie, awaria lub postęp, wraz z wszelkimi danymi powiązanymi z tym zdarzeniem (takimi jak wynik zapytania do bazy danych lub komunikat o błędzie), a główny wątek węzła decyduje, co zrobić z tymi danymi.

Możesz przeczytać więcej na ten temat tutaj: Jak działa jednowątkowy, nieblokujący model IO w Node.js

 190
Author: Salvatorelab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:25

Różnica między tymi dwoma podejściami jest następująca:

Sposób synchroniczny: Czeka na zakończenie każdej operacji, potem tylko wykonuje następną operację. Dla Twojego zapytania: Polecenie console.log() zostanie wykonane dopiero po&, chyba że zapytanie zakończy wykonywanie, aby pobrać wszystkie wyniki z bazy danych.

Asynchroniczny sposób: Nigdy nie czeka na zakończenie każdej operacji, raczej wykonuje wszystkie operacje tylko przy pierwszym uruchomieniu. Wynik każdego operacja zostanie przeprowadzona, gdy wynik będzie dostępny. Dla Twojego zapytania: Polecenie {[0] } zostanie wykonane wkrótce po metodzie Database.Query(). Podczas gdy zapytanie bazy danych działa w tle i ładuje wynik po zakończeniu pobierania danych.

Przypadki użycia

  1. Jeśli Twoje operacje nie wykonują bardzo ciężkich zadań, takich jak odpytywanie ogromnych danych z DB, to idź do przodu z synchronicznym sposobem, w przeciwnym razie asynchronicznym sposobem.

  2. W sposób asynchroniczny można Pokaż jakiś wskaźnik postępu użytkownikowi, podczas gdy w tle możesz kontynuować swoje ciężkie prace. Jest to idealny scenariusz dla aplikacji GUI.

 62
Author: Santosh Panda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-27 08:54:10

Stanie się to nieco bardziej jasne, jeśli dodasz wiersz do obu przykładów:

var result = database.query("SELECT * FROM hugetable");
console.log(result.length);
console.log("Hello World");

Drugi:

database.query("SELECT * FROM hugetable", function(rows) {
   var result = rows;
   console.log(result.length);
});
console.log("Hello World");

Spróbuj je uruchomić, a zauważysz, że pierwszy (synchroniczny) przykład, wynik.Długość zostanie wydrukowana przed wierszem "Hello World". W drugim przykładzie (asynchronicznym) wynik.Długość zostanie (najprawdopodobniej) wydrukowana po wierszu "Hello World".

Dlatego, że w drugim przykładzie {[2] } jest uruchamiany asynchronicznie w tle, a scenariusz kontynuuje od razu "Hello World". console.log(result.length) jest wykonywane tylko wtedy, gdy zapytanie bazy danych zostało zakończone.

 20
Author: Martijn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-02 11:08:11

Po pierwsze, zdaję sobie sprawę, że jestem spóźniony w odpowiedzi na to pytanie.

Zanim omówimy synchroniczne i asynchroniczne, przyjrzyjmy się krótko, jak działają programy.

W przypadkusynchronous każde polecenie uzupełnia przed uruchomieniem następnego polecenia. W tym przypadku program jest oceniany dokładnie w kolejności instrukcji.

Tak działa asynchroniczny w JavaScript. Istnieją dwie części w silniku JavaScript, jedna część, która patrzy na kod oraz operacje enqueues i inne, które przetwarzają kolejkę. Przetwarzanie kolejki odbywa się w jednym wątku, dlatego tylko jedna operacja może się zdarzyć na raz.

Gdy widzi się operację asynchroniczną (jak drugie zapytanie bazy danych), kod jest przetwarzany i operacja jest umieszczana w kolejce, ale w tym przypadku rejestrowane jest wywołanie zwrotne, które zostanie uruchomione po zakończeniu tej operacji. Kolejka może mieć już wiele operacji. Operacja na początku kolejki jest przetwarzana i usuwana z kolejki. Po przetworzeniu operacji dla zapytania bazy danych żądanie jest wysyłane do bazy danych, a po zakończeniu wywołania zwrotnego zostanie wykonane po zakończeniu. W tym czasie procesor kolejki, który "obsłużył" operację, przechodzi do następnej operacji-w tym przypadku

    console.log("Hello World"); 

Zapytanie do bazy danych jest nadal przetwarzane, ale konsola.operacja logowania znajduje się na początku kolejki i jest przetwarzana. Jest to operacja synchroniczna wykonywana od razu w wyniku natychmiast w wyjściu "Hello World". Jakiś czas później operacja bazy danych zostanie zakończona, dopiero wtedy wywołana i przetworzona zostanie callback zarejestrowany z zapytaniem, ustawiając wartość zmiennej result na wiersze.

Jest możliwe, że jedna operacja asynchroniczna spowoduje kolejną operację asynchroniczną, ta druga operacja zostanie umieszczona w kolejce i jeśli chodzi o początek kolejki, zostanie przetworzona. Wywołanie wywołania zwrotnego zarejestrowanego przy operacji asynchronicznej jak JavaScript run time zwraca wynik operacji po jej wykonaniu.

Prostą metodą sprawdzania, która operacja JavaScript jest asynchroniczna, jest zanotowanie, czy wymaga wywołania zwrotnego - callback 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 tych dwóch. Nie zawsze tak jest ze względu na różne style obsługi wynik operacji asynchronicznej.

Aby dowiedzieć się więcej, przeczytaj o obietnicach. Obietnice są Innym sposobem, w jaki można obsłużyć wynik operacji asynchronicznej. Fajną rzeczą w obietnicach jest to, że styl kodowania jest bardziej podobny do kodu synchronicznego.

Wiele bibliotek, takich jak node 'fs', zapewnia zarówno synchroniczne, jak i asynchroniczne style 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 - synchroniczne działanie stylu spowoduje, że kod będzie łatwiejszy do odczytania.

 17
Author: Jay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 12:31:26

W przypadku synchronicznym konsola.polecenie log jest wykonywane dopiero po zakończeniu wykonywania zapytania SQL.

W przypadku asynchronicznym konsola.polecenie log zostanie wykonane bezpośrednio. Wynik zapytania zostanie następnie zapisany przez funkcję "callback".

 5
Author: related,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-02 11:04:30

Główna różnica polega na programowaniu asynchronicznym, inaczej nie przerywa się wykonywania. Możesz kontynuować wykonywanie innego kodu podczas wykonywania 'request'.

 4
Author: thebreiflabb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-02 11:03:08

Funkcja sprawia, że drugi jest asynchroniczny.

Pierwszy zmusza program do czekania na zakończenie każdej linii, zanim następna będzie mogła kontynuować. Druga pozwala na jednoczesne (i niezależne) bieganie każdej linii.

Języki i frameworki (js, node.js), które pozwalają na asynchroniczną lub współbieżną jest Świetne dla rzeczy, które wymagają transmisji w czasie rzeczywistym (np. czat, aplikacje giełdowe).

 2
Author: Anton Chan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-17 19:37:26

Programowanie Sync

Języki programowania takie jak C, C#, Java są programowaniem synchronicznym, to co kiedykolwiek napiszesz będzie wykonywane w kolejności pisania.

-GET DATA FROM SQL.
//Suppose fetching data take 500 msec

-PERFORM SOME OTHER FUNCTION.
//Performing some function other will take 100 msec, but execution of other 
//task start only when fetching of sql data done (i.e some other function 
//can execute only after first in process job finishes).

-TOTAL TIME OF EXECUTION IS ALWAYS GREATER THAN (500 + 100 + processing time) 
msec

Async

NodeJs pojawia się z funkcją asynchroniczną, nie blokuje się w naturze, Załóżmy, że w każdym zadaniu We / Wy, które zajmuje czas (pobieranie, pisanie, czytanie), nodejs nie będzie bezczynnie czekać na zakończenie zadania, zacznie wykonywać kolejne zadania w kolejce i za każdym razem, gdy zadanie zajmie czas wypełniony powiadomi za pomocą wywołania zwrotnego. Poniższy przykład pomoże:

//Nodejs uses callback pattern to describe functions.
//Please read callback pattern to understand this example

//Suppose following function (I/O involved) took 500 msec
function timeConsumingFunction(params, callback){
  //GET DATA FROM SQL
  getDataFromSql(params, function(error, results){
    if(error){
      callback(error);
    }
    else{
      callback(null, results);
    }
  })
}

//Suppose following function is non-blocking and took 100 msec
function someOtherTask(){
  //some other task
  console.log('Some Task 1');
  console.log('Some Task 2');
}

console.log('Execution Start');

//Start With this function
timeConsumingFunction(params, function(error, results){
    if(error){
      console.log('Error')
    }
    else{
      console.log('Successfull'); 
    }
  })

//As (suppose) timeConsumingFunction took 500 msec, 
//As NodeJs is non-blocking, rather than remain idle for 500 msec, it will start 
//execute following function immediately
someOtherTask();

W skrócie, wyjście to:

Execution Start
//Roughly after 105 msec (5 msec it'll take in processing)
Some Task 1
Some Task 2
//Roughly After 510 msec
Error/Successful //depends on success and failure of DB function execution

Różnica jest jasna, gdzie synchronizacja na pewno zajmie więcej niż 600 (500 + 100 + Czas Przetwarzania) msec, async oszczędza czas.

 0
Author: Neeraj Bansal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-07 12:21:59