Poiché JavaScript viene eseguito in un singolo thread, dopo che è stata effettuata una richiesta AJAX, cosa succede effettivamente in background? Vorrei approfondire questo aspetto, qualcuno può far luce?
Poiché JavaScript viene eseguito in un singolo thread, dopo che è stata effettuata una richiesta AJAX, cosa succede effettivamente in background? Vorrei approfondire questo aspetto, qualcuno può far luce?
Risposte:
Sotto le copertine, JavaScript ha una coda di eventi. Ogni volta che termina un thread di esecuzione javascript, controlla se esiste un altro evento nella coda da elaborare. Se c'è, lo estrae dalla coda e attiva quell'evento (come un clic del mouse, per esempio).
La rete del codice nativo che si trova sotto la chiamata ajax saprà quando la risposta ajax è stata eseguita e un evento verrà aggiunto alla coda degli eventi javascript. Il modo in cui il codice nativo sa quando viene eseguita la chiamata ajax dipende dall'implementazione. Può essere implementato con thread o può anche essere guidato dagli eventi (non importa davvero). Il punto dell'implementazione è che quando viene eseguita la risposta ajax, alcuni codici nativi sapranno che è stato fatto e inseriscono un evento nella coda JS.
Se al momento non è in esecuzione JavaScript, l'evento verrà immediatamente attivato e verrà eseguito il gestore della risposta ajax. Se qualcosa è in esecuzione al momento, l'evento verrà elaborato al termine dell'attuale thread di esecuzione javascript. Non è necessario alcun polling da parte del motore JavaScript. Quando un pezzo di Javascript termina l'esecuzione, il motore JS controlla semplicemente la coda degli eventi per vedere se c'è qualcos'altro che deve essere eseguito. In tal caso, elimina l'evento successivo dalla coda ed esegue (chiamando una o più funzioni di callback registrate per quell'evento). Se nella coda degli eventi non è presente nulla, l'interprete JS ha tempo libero (garbage collection o inattivo) fino a quando un agente esterno inserisce qualcos'altro nella coda degli eventi e lo riattiva.
Poiché tutti gli eventi esterni passano attraverso la coda degli eventi e nessun evento viene mai attivato mentre javascript esegue effettivamente qualcos'altro, rimane a thread singolo.
Ecco alcuni articoli sui dettagli:
.focus()
un elemento e ciò attiva un paio di altri eventi come un evento di "sfocatura" sull'elemento con lo stato attivo. Quell'evento di sfocatura si verifica in modo sincrono e non passa attraverso la coda degli eventi, quindi accadrebbe immediatamente prima di altre cose che potrebbero trovarsi nella coda degli eventi. In pratica, non ho mai trovato questo un problema pratico.
Puoi trovare qui una documentazione molto completa sulla gestione degli eventi in javascript.
È scritto da un ragazzo che sta lavorando all'implementazione di JavaScript nel browser Opera.
Più precisamente, guarda i titoli: "Flusso di eventi", "Accodamento eventi" e "Eventi non utente": imparerai che:
Nota: il link originale era: link , ma ora è morto.
Voglio elaborare un po ', per quanto riguarda l'implementazione ajax menzionata nelle risposte.
Sebbene l'esecuzione (regolare) di Javascript non sia multi-thread - come notato bene nelle risposte sopra - tuttavia , la gestione reale del AJAX responses
(così come la gestione della richiesta) non è Javascript, e - di solito - è multi-thread. (vedi l'implementazione della fonte di cromo di XMLHttpRequest di cui parleremo sopra)
e ti spiego, prendiamo il seguente codice:
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
(- dopo il passaggio 1), quindi mentre l'esecuzione del codice js (passaggio 2 e successivi), il browser avvia il vero lavoro di: 1. formattazione di una richiesta tcp 2. apertura di un socket 3. invio di intestazioni 4. handshaking 5. invio body 6. in attesa di risposta 7. lettura delle intestazioni 8. lettura del body ecc. tutta questa implementazione è di solito eseguita in un thread diverso in parallelo all'esecuzione del codice js. per esempio, l'implementazione del cromo menzionata usa Threadable Loader go digg-into 😉, (puoi anche avere qualche impressione guardando la scheda di rete di un caricamento di pagina, vedrai alcune richieste simultanee).
in conclusione, direi che - almeno - la maggior parte delle operazioni di I / O può essere effettuata simultaneamente / asincrona (e puoi approfittarne usando ad esempio un wait ). ma tutte le interazioni con tali operazioni (emissione, esecuzione di callback js) sono tutte sincrone.