W kontekście silników JavaScript po stronie serwera, czym jest nieblokujące we / wy lub asynchroniczne operacje we / wy? Widzę, że wspomina się o tym jako o przewadze nad implementacjami po stronie serwera Java.
W kontekście silników JavaScript po stronie serwera, czym jest nieblokujące we / wy lub asynchroniczne operacje we / wy? Widzę, że wspomina się o tym jako o przewadze nad implementacjami po stronie serwera Java.
Odpowiedzi:
Synchroniczne wykonanie zwykle odnosi się do kodu wykonywanego w sekwencji. Wykonywanie asynchroniczne odnosi się do wykonywania, które nie jest uruchamiane w kolejności, w jakiej występuje w kodzie. W poniższym przykładzie operacja synchroniczna powoduje uruchomienie alertów w sekwencji. Podczas operacji asynchronicznej, podczas gdy alert(2)
wydaje się być wykonywana jako druga, tak się nie dzieje.
Synchroniczne: 1, 2, 3
alert(1);
alert(2);
alert(3);
Asynchroniczne: 1,3,2
alert(1);
setTimeout(() => alert(2), 0);
alert(3);
Blokowanie odnosi się do operacji, które blokują dalsze wykonywanie do zakończenia tej operacji. Nieblokowanie odnosi się do kodu, który nie blokuje wykonania. W podanym przykładzie localStorage
jest to operacja blokująca, ponieważ wstrzymuje wykonywanie odczytu. Z drugiej strony fetch
jest operacją nieblokującą, ponieważ nie wstrzymuje alert(3)
wykonania.
// Blocking: 1,... 2
alert(1);
var value = localStorage.getItem('foo');
alert(2);
// Non-blocking: 1, 3,... 2
alert(1);
fetch('example.com').then(() => alert(2));
alert(3);
Jedną z zalet nieblokujących, asynchronicznych operacji jest to, że można zmaksymalizować użycie pojedynczego procesora oraz pamięci.
Przykładem synchronicznych operacji blokujących jest sposób, w jaki niektóre serwery WWW, takie jak serwery Java lub PHP, obsługują żądania we / wy lub żądania sieciowe. Jeśli twój kod czyta z pliku lub bazy danych, twój kod „blokuje” wykonanie wszystkiego po nim. W tym okresie Twoja maszyna zatrzymuje pamięć i czas przetwarzania dla wątku, który nic nie robi .
Aby zaspokoić inne żądania, gdy ten wątek utknął, zależy od oprogramowania. Większość oprogramowania serwerowego tworzy więcej wątków, aby obsłużyć dodatkowe żądania. Wymaga to większej ilości pamięci i przetwarzania.
Asynchroniczne, nieblokujące serwery - takie jak te wykonane w Node - używają tylko jednego wątku do obsługi wszystkich żądań. Oznacza to, że wystąpienie Node maksymalnie wykorzystuje pojedynczy wątek. Twórcy zaprojektowali go z założeniem, że wąskim gardłem są operacje we / wy i operacje sieciowe.
Kiedy żądania docierają do serwera, są obsługiwane pojedynczo. Jednak gdy obsługiwany kod musi na przykład zapytać o bazę danych, wysyła wywołanie zwrotne do drugiej kolejki, a główny wątek będzie kontynuował działanie (nie czeka). Teraz, gdy operacja bazy danych zakończy się i powróci, odpowiednie wywołanie zwrotne jest wyciągane z drugiej kolejki i umieszczane w kolejce w trzeciej kolejce, gdzie oczekuje na wykonanie. Kiedy silnik ma szansę wykonać coś innego (np. Gdy stos wykonania jest opróżniany), odbiera wywołanie zwrotne z trzeciej kolejki i wykonuje go.
var startTime = new Date().getTime();
var getEndTime = () => {
var tempEndTime = new Date().getTime();
var second = (tempEndTime - startTime)/1000
return `took ${second} sec...to finish\n`
}
console.log('1: start App', getEndTime())
setTimeout(()=>{
console.log('2: setTimeout', getEndTime())
}, 1000)
console.log('3: End App', getEndTime())
// console -> Process Order: 1 -> 3 -> 2