2016-04-05 13 views
8

ho il seguente codice:uscite non numeri Perché setTimeout in ordine aggiunto

function wait(ms) { 
    var start = +(new Date()); 
    while (new Date() - start < ms); 
} 

(function() { 
    setTimeout(function(){console.log(2)}, 1000); 
    setTimeout(function(){console.log(3)}, 0); 
    setTimeout(function(){console.log(4)}, 0); 
    wait(2000); //!!! blocking events processing here 
})(); 

Produce:

3 
4 
2 

Ho letto da qualche parte che setTimeout aggiunge funzione al event queue, e poi quando questa funzione è la prima nella catena che controlla se la quantità di tempo specificata è passata, in caso contrario, posticipa l'esecuzione. In base a questa logica mi aspettavo che il codice di cui sopra venisse emesso: 2,3,4 dal wait() l'elaborazione della concatenazione degli eventi dei blocchi funzione e uno stack di chiamate è stato completato e un browser ha finalmente il tempo di elaborare le funzioni aggiunte attraverso setTimeout, tutte e tre le funzioni sono inserite nella coda nell'ordine aggiunto e 1000 sono già passati per la prima funzione, quindi un browser può prenderlo ed eseguirlo, ma attende le funzioni aggiunte secondo e terzo. Perché? Dov'è l'errore nella mia logica?

+4

L'unica cosa 'garanzie setTimeout' è che le richiamate saranno eseguite * almeno altrettanto molti millisecondi in futuro * come richiesto. Nessuno ha detto nulla sulla garanzia di un ordine specifico. – deceze

risposta

9

La funzione di richiamata entra nella coda dopo il il periodo di timeout. Così,

setTimeout(function(){console.log(3)}, 0); 
setTimeout(function(){console.log(4)}, 0); 

entra immediatamente, ma

setTimeout(function(){console.log(2)}, 1000); 

entra nella coda dopo 1 secondo. Da qui l'ordine 3,4,2

Da MDN:

chiamata setTimeout aggiungerà un messaggio alla coda dopo il tempo passato come secondo argomento. Se non ci sono altri messaggi nella coda, il messaggio viene elaborato subito; tuttavia, se ci sono messaggi, il messaggio setTimeout dovrà attendere l'elaborazione di altri messaggi. Per questo motivo il secondo argomento indica un tempo minimo e non un tempo garantito.

(sottolineatura mia)