2016-02-09 21 views
5

Date un'occhiata a questo esempio:La coda eventi Javascript è un semplice FIFO o no?

function A() { console.log('A'); } 
function B() { console.log('B'); } 
// and then i setTimeout(fn, 0) both of them 
setTimeout(A, 0); 
setTimeout(B, 0); 

E 'guarantied che B immediatamente correre dietro A?
È possibile che il browser aggiunga un'altra attività in coda tra A e B?

nota: nessuna delle funzioni A o B aggiunge nuove attività al ciclo degli eventi.

var callbacks = []; 
// then add a bunch of callbacks ... (none adds events to event queue) 
//case 1: 
callbacks.forEach(cb => setTimeout(cb,0)) 
//case 2: 
setTimeout(function() { 
    callbacks.forEach(cb => cb()); 
},0); 

ci sono delle differenze nel l'ordine di esecuzione di callback in case 1 vs case 2?

+0

Risposta semplice: no, non c'è alcuna garanzia. Perché questa coda è utilizzata da molte altre cose oltre al motore JS. –

+0

viene utilizzato contemporaneamente? ed è possibile che un evento da "DOM" venga posto in coda mentre una parte di js è in esecuzione? (non è js single thread? e gli script js long running fermano il freeze del browser?) –

risposta

3

E 'guarantied che B immediatamente eseguito dopo A?

Non immediatamente, no, ma è garantito che B verrà eseguito dopo A. I dettagli completi in the spec, ma in breve, questo è specificamente indirizzata nel timer initialization steps, che dire in parte:

Attendere fino a quando tutte le invocazioni di questo algoritmo, che aveva lo stesso contesto metodo, che ha iniziato prima di questo, e il cui timeout è uguale o minore di questo, aver completato.

Opzionalmente, attendere un ulteriore intervallo definito dall'utente definito dall'utente.

Accodare l'attività attività.

... dove compito è il compito di chiamare la richiamata hai dato setTimeout.

La coda di attività deve essere eseguita in ordine e pertanto A verrà eseguito prima di B in un browser compatibile.

Si noti che questo è garantito perché sono stati accodati dallo stesso contesto di metodo (vedere le specifiche per i dettagli di ciò che significa).

È possibile che il browser aggiunga un'altra attività in coda tra A e B?

Sì. Il browser può essere multi-thread e mettere in coda un'attività per qualche altra cosa (un messaggio da un web worker, ecc.) Tra le code in coda per le attività per A e B. In tal caso, vedrai eseguire A, quindi il gestore per l'altra attività (elaborazione del messaggio dal web worker o qualsiasi altra cosa), quindi B.

1

Si accenderanno sempre nell'ordine corretto, A quindi B. Tuttavia, è possibile che non esegua il fuoco consecutivamente.

Infatti, the specification says che timeout callback non sono nemmeno posti sulla coda di esecuzione fino a quando il timer è trascorso, che possono essere oggetto di ulteriori ritardi - il timeout specificato è soltanto un minimo quantità di tempo per aspettare .

+0

E 'possibile che un'altra operazione dica "C" tra "A" e "B"? –

+0

'potrebbero non attivarsi consecutivamente' ... ma il timeout è zero ... –

+0

Sì, è possibile. Sebbene improbabile, il motore stesso è multithreaded e potrebbe ricevere un altro evento da accodare tra l'aggiunta di 'A' alla coda e l'aggiunta di' B' alla coda. –

-1

Sì, se yo provare questo:

function A() { console.log('A'); } 
function B() { console.log('B'); } 
function C() { while(1) { console.log('C'); } } 
// and then i setTimeout(fn, 0) both of them 
setTimeout(A, 0); 
setTimeout(C, 0); 
setTimeout(B, 0); 

Si vedrà che la funzione C ha un ciclo infinito, quindi non è mai viene eseguita la funzione B. Questo perché le funzioni passati al compito/lista degli eventi ed esegui come questi fine. Questo è in relazione alla lista degli eventi. Il setTimeout ha un modo particolare di lavorare. ma, se lo chiedi.

D'altra parte, se si chiede se il caso verrà mai eseguito per primo, seguito da B, la risposta non è una garanzia perché si verificano perché non sono gli unici eventi che possono essere eseguiti.