2011-11-01 18 views
5

Ho sempre sentito che JavaScript è a thread singolo; che quando JavaScript viene eseguito, viene eseguito tutto nello stesso mosh pit globale, il tutto in un singolo thread.JavaScript e single-threaded

Anche se ciò può essere vero, quel singolo thread di esecuzione può generare nuovi thread, ripristinando asincronicamente i dati sul thread principale, correggere? Ad esempio, quando viene inviato un XMLHttpRequest, il browser non crea un nuovo thread che esegue la transazione HTTP, quindi richiama nuovamente le callback nel thread principale quando XMLHttpRequest restituisce?

E i timer: setTimeout e setInterval? Come funzionano?

Questa filatura è il risultato della lingua? Cosa ha impedito a JavaScript di avere un'esecuzione multi-thread prima della bozza dei nuovi Web Workers?

+0

Gli interpreti javaScript condividono spesso il thread dell'interfaccia utente del browser – david

+2

la prossima volta che sto parlando di ambito globale, userò il termine ** global mosh pit ** :) –

+0

inb4 HTML5 web worker – Ben

risposta

3

Vedere this post per una descrizione di come funziona la coda di eventi javascript, incluso il modo in cui è correlata alle chiamate ajax.

Il browser utilizza sicuramente almeno un thread/processo OS nativo per gestire l'interfaccia effettiva del sistema operativo per recuperare gli eventi di sistema (mouse, tastiera, timer, eventi di rete, ecc.). Il fatto che esista più di un thread nativo a livello di sistema operativo dipende dall'implementazione del browser e non è realmente rilevante per il comportamento di Javascript. Tutti gli eventi dal mondo esterno passano attraverso la coda degli eventi javascript e nessun evento viene elaborato fino a quando non viene completato un precedente thread di esecuzione javascript e l'evento successivo viene quindi estratto dalla coda assegnata al motore javascript.

4

Lo stesso codice JavaScript è a thread singolo. Può, tuttavia, interagire con altri thread nel browser (che viene spesso scritto con qualcosa come C e C++). Questo è il modo in cui il lavoro XHR asincrono. Il browser può creare un nuovo thread (oppure può riutilizzarne uno esistente con un loop eventi)

I timer e gli intervalli proveranno a far funzionare il tuo JavaScript più tardi, ma se hai un while(1){ ; } in esecuzione non aspettarti un timer o un intervallo per interromperlo.

(modifica: lasciato fuori qualcosa.) La filettatura singola è in gran parte un risultato della specifica ECMA. Non ci sono davvero costrutti di linguaggio per gestire più thread. Non sarebbe impossibile scrivere un interprete JavaScript con più thread e gli strumenti per interagire con loro, ma nessuno lo fa davvero. Certamente nessuno lo farà in un browser web; farebbe confusione con lo su tutto. (Se stai facendo qualcosa sul lato server come Node.js, vedrai che hanno evitato il multithreading nel JavaScript corretto a favore di un loop di eventi snella e multielaborazione facoltativa.)

6

XMLHttpRequest, in particolare , non blocca il thread corrente. Tuttavia, le sue specifiche all'interno del runtime non sono delineate in alcuna specifica. Può essere eseguito in un thread separato o all'interno del thread corrente, facendo uso di I/O non bloccante.

setTimeout e setInterval timer di fermo che, quando eseguito fino a zero, aggiungere un elemento per l'esecuzione, sia una linea di codice di una funzione/callback per lo stack di esecuzione, avviare il motore JavaScript se l'esecuzione di codice è fermato. In altre parole, dicono al motore JavaScript di fare qualcosa dopo che ha finito di fare qualsiasi cosa stia facendo al momento. Per vedere questo in azione, imposta più setTimeout (s) all'interno di un metodo e chiamalo.

0

Il browser potrebbe avere altri thread per eseguire il lavoro ma il codice Javascript verrà comunque eseguito in un thread. Ecco come funzionerebbe nella pratica.

In caso di timeout, il browser creerà un thread separato per attendere che scada il timeout o utilizzare qualche altro meccanismo per implementare la logica di temporizzazione effettiva. Al termine del timeout, il messaggio verrà posizionato sulla coda degli eventi principale che indica al runtime di eseguire il gestore. e ciò accadrà non appena il messaggio viene raccolto dal thread principale.

La richiesta AJAX funzionerebbe allo stesso modo. Alcuni thread interni del browser potrebbero effettivamente connettersi al server e attendere la risposta e una volta che la risposta è disponibile, inserire il messaggio appropriato sulla coda degli eventi principale in modo che il thread principale esegua il gestore.

In tutti i casi il codice verrà eseguito dal thread principale. Questo non è diverso dalla maggior parte degli altri sistemi di interfaccia utente, tranne che il browser nasconde quella logica da te. Su altre piattaforme potresti aver bisogno di gestire thread separati e assicurare l'esecuzione dei gestori sul thread dell'interfaccia utente.

0

Mettendolo più semplicemente che parlando in termini di thread, in generale (per i browser di cui sono a conoscenza) ci sarà solo un blocco di esecuzione di JavaScript in un dato momento.

Quando si effettua una richiesta Ajax asincrono o chiamare setTimeout o setInterval il browser potrebbe gestire loro in un altro thread, ma il codice vero e JS nelle callback non eseguirà fino a qualche punto dopo il blocco attualmente in esecuzione del codice di finiture. Viene semplicemente messo in coda.

Un semplice test per dimostrare questo è se si mette un pezzo di codice in esecuzione relativamente lungo dopo un setTimeout, ma nello stesso blocco:

setTimeout("alert('Timeout!');", 5); 
alert("After setTimeout; before loop");  
for (var i=0, x=0; i < 2000000; i++) { x += i }; 
alert("After loop"); 

Se si esegue quanto sopra vedrete la "Dopo setTimeout "alert, quindi ci sarà una pausa mentre il ciclo è in esecuzione, quindi vedrai" After loop ", e solo dopo vedrai" Timeout! " - anche se chiaramente è passato molto più di 5 ms (specialmente se ci vuole un po 'per chiudere il primo avviso).

Un motivo spesso citato per il thread singolo è che semplifica il lavoro del browser di rendering della pagina, perché non si ottiene la situazione di molti thread diversi di JavaScript che tentano di aggiornare il DOM allo stesso tempo.

0

Javascript è un linguaggio progettato per essere incorporato. Può e è stato utilizzato in programmi che eseguono javascript contemporaneamente su thread operativi diversi. Non c'è molta richiesta di un linguaggio incorporato per controllare esplicitamente la creazione di nuovi thread di esecuzione, ma potrebbe certamente essere fatto fornendo un oggetto host con le funzionalità richieste. Il WHATWG in realtà includes a justification for their decision not to push a standard concurrent execution capability for browsers.