Ponieważ JavaScript działa w jednym wątku, po wysłaniu żądania AJAX, co właściwie dzieje się w tle? Chciałbym uzyskać głębszy wgląd w to, czy ktoś może rzucić trochę światła?
Ponieważ JavaScript działa w jednym wątku, po wysłaniu żądania AJAX, co właściwie dzieje się w tle? Chciałbym uzyskać głębszy wgląd w to, czy ktoś może rzucić trochę światła?
Odpowiedzi:
Pod okładkami javascript ma kolejkę zdarzeń. Za każdym razem, gdy kończy się wątek wykonywania javascript, sprawdza, czy w kolejce jest inne zdarzenie do przetworzenia. Jeśli tak, to wyciąga go z kolejki i wyzwala to zdarzenie (na przykład kliknięcie myszą).
Natywny kod sieciowy, który znajduje się pod wywołaniem Ajax, będzie wiedział, kiedy odpowiedź Ajax zostanie wykonana, a zdarzenie zostanie dodane do kolejki zdarzeń javascript. Skąd kod natywny wie, kiedy wywołanie AJAX jest wykonywane, zależy od implementacji. Może być zaimplementowany za pomocą wątków lub może być sterowany zdarzeniami (nie ma to większego znaczenia). Celem implementacji jest to, że gdy odpowiedź AJAX jest zakończona, jakiś natywny kod będzie wiedział, że to jest zrobione i umieści zdarzenie w kolejce JS.
Jeśli żaden JavaScript nie jest uruchomiony w danym momencie, zdarzenie zostanie natychmiast wyzwolone, co uruchomi moduł obsługi odpowiedzi Ajax. Jeśli coś jest uruchomione w tym czasie, zdarzenie zostanie przetworzone po zakończeniu bieżącego wątku wykonywania javascript. Nie ma potrzeby odpytywania przez silnik javascript. Po zakończeniu wykonywania fragmentu JavaScript silnik JS sprawdza kolejkę zdarzeń, aby sprawdzić, czy jest jeszcze coś, co należy uruchomić. Jeśli tak, zdejmuje następne zdarzenie z kolejki i wykonuje je (wywołując jedną lub więcej funkcji zwrotnych zarejestrowanych dla tego zdarzenia). Jeśli nic nie znajduje się w kolejce zdarzeń, interpreter JS ma wolny czas (czyszczenie pamięci lub bezczynność) do momentu, gdy jakiś zewnętrzny agent umieści coś innego w kolejce zdarzeń i ponownie ją obudzi.
Ponieważ wszystkie zdarzenia zewnętrzne przechodzą przez kolejkę zdarzeń i żadne zdarzenie nie jest nigdy wyzwalane, gdy javascript faktycznie uruchamia coś innego, pozostaje on jednowątkowy.
Oto kilka artykułów na temat szczegółów:
.focus()
element, a to wywołuje kilka innych zdarzeń, takich jak zdarzenie „rozmycia” elementu, na którym jest fokus. To zdarzenie rozmycia odbywa się synchronicznie i nie przechodzi przez kolejkę zdarzeń, więc wydarzy się od razu przed innymi rzeczami, które mogą znajdować się w kolejce zdarzeń. W praktyce nigdy nie uważałem tego za praktyczny problem.
Znajdziesz tutaj bardzo kompletną dokumentację dotyczącą obsługi zdarzeń w javascript.
Został napisany przez gościa pracującego nad implementacją javascript w przeglądarce Opera.
Dokładniej, spójrz na tytuły: „Przebieg zdarzeń”, „Kolejkowanie zdarzeń” i „Zdarzenia nie-użytkowników”: dowiesz się, że:
Uwaga: oryginalny link to: link , ale teraz jest martwy.
Chcę trochę rozwinąć, odnośnie implementacji Ajax wspomnianej w odpowiedziach.
Chociaż (zwykłe) wykonanie JavaScript nie jest wielowątkowe - jak zauważono w powyższych odpowiedziach - jednak rzeczywista obsługa AJAX responses
(podobnie jak obsługa żądań) nie jest JavaScriptem i - zwykle - jest wielowątkowa. (zobacz implementację XMLHttpRequest dla źródła chromu, którą omówimy powyżej)
i wyjaśnię, weźmy następujący kod:
var xhr = new XMLHttpRequest();
var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );
xhr.onload = function( e ) {
console.log(t() + ': step 3');
alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');
after an AJAX request is made
(- po kroku 1), a następnie w trakcie wykonywania kodu js (krok 2 i później) przeglądarka rozpoczyna rzeczywistą pracę polegającą na: 1. formatowaniu żądania tcp 2. otwieraniu gniazda 3. wysyłaniu nagłówków 4. uzgadnianiu 5. wysyłaniu body 6. odpowiedź oczekująca 7. odczyt nagłówków 8. odczyt treści itp. Cała ta implementacja jest zwykle uruchamiana w innym wątku równolegle do wykonywania kodu js. na przykład, wspomniana implementacja chromu używa Threadable Loader aby zagłębić się w 😉 (możesz również odnieść wrażenie, patrząc na kartę sieciową ładowania strony, zobaczysz kilka jednoczesnych żądań).
Podsumowując, powiedziałbym, że - przynajmniej - większość operacji we / wy może być wykonywana jednocześnie / asynchronicznie (i można to wykorzystać, na przykład, używając await ). ale wszystkie interakcje z tymi operacjami (wydawanie, wykonanie wywołania zwrotnego js) są synchroniczne.