Qual è la differenza tra questi due e quando ne userò uno sull'altro?
Qual è la differenza tra questi due e quando ne userò uno sull'altro?
Risposte:
setTimeout è semplicemente come chiamare la funzione dopo che il ritardo è terminato. Ogni volta che una funzione viene chiamata, non viene eseguita immediatamente, ma messa in coda in modo che venga eseguita dopo che tutti i gestori di eventi in esecuzione e attualmente in coda terminano per primi. setTimeout (, 0) significa essenzialmente eseguire dopo che tutte le funzioni correnti nella coda attuale sono state eseguite. Non è possibile fornire garanzie su quanto tempo potrebbe richiedere.
setImmediate è simile a questo proposito tranne per il fatto che non usa la coda di funzioni. Controlla la coda dei gestori di eventi I / O. Se tutti gli eventi I / O nell'istantanea corrente vengono elaborati, esegue la richiamata. Li mette in coda immediatamente dopo l'ultimo gestore I / O un po 'come process.nextTick. Quindi è più veloce.
Inoltre (setTimeout, 0) sarà lento perché controllerà il timer almeno una volta prima dell'esecuzione. A volte può essere due volte più lento. Ecco un punto di riferimento.
var Suite = require('benchmark').Suite
var fs = require('fs')
var suite = new Suite
suite.add('deffered.resolve()', function(deferred) {
deferred.resolve()
}, {defer: true})
suite.add('setImmediate()', function(deferred) {
setImmediate(function() {
deferred.resolve()
})
}, {defer: true})
suite.add('setTimeout(,0)', function(deferred) {
setTimeout(function() {
deferred.resolve()
},0)
}, {defer: true})
suite
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
.run({async: true})
Produzione
deffered.resolve() x 993 ops/sec ±0.67% (22 runs sampled)
setImmediate() x 914 ops/sec ±2.48% (57 runs sampled)
setTimeout(,0) x 445 ops/sec ±2.79% (82 runs sampled)
Il primo dà un'idea delle chiamate possibili più veloci. Puoi controllare tu stesso se setTimeout viene chiamato la metà delle volte di altri. Ricorda anche che setImmediate si adatterà alle chiamate del tuo filesystem. Quindi sotto carico funzionerà meno. Non credo che setTimeout possa fare di meglio.
setTimeout è un modo non invadente di chiamare le funzioni dopo un po 'di tempo. È proprio come nel browser. Potrebbe non essere adatto per il lato server (pensa perché ho usato benchmark.js non setTimeout).
Un ottimo articolo su come funziona il ciclo di eventi e cancella alcune idee sbagliate. http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
Citando l'articolo:
setImmediatei callback vengono chiamati dopo che i callback della coda I / O sono terminati o scaduti. setImmediate callback vengono inseriti in Check Queue, che vengono elaborati dopo I / O Queue.
setTimeout(fn, 0)i callback vengono inseriti in Timer Queue e verranno chiamati dopo i callback I / O e dopo i callback Check Queue. Come ciclo di eventi, elabora prima la coda del timer in ogni iterazione, quindi quale verrà eseguita per prima dipende da quale fase è il ciclo di eventi.
setImmediate () serve a pianificare l'esecuzione immediata del callback dopo i callback degli eventi I / O e prima di setTimeout e setInterval.
setTimeout () serve per pianificare l'esecuzione di una richiamata una tantum dopo un ritardo di millisecondi.
Questo è ciò che dicono i documenti.
setTimeout(function() {
console.log('setTimeout')
}, 0)
setImmediate(function() {
console.log('setImmediate')
})
Se esegui il codice precedente, il risultato sarà come questo ... anche se il documento corrente afferma che "Per pianificare l'esecuzione" immediata "del callback dopo i callback degli eventi I / O e prima di setTimeout e setInterval." ..
Risultato..
setTimeout
setImmediate
Se racchiudi il tuo esempio in un altro timer, stampa sempre setImmediate seguito da setTimeout.
setTimeout(function() {
setTimeout(function() {
console.log('setTimeout')
}, 0);
setImmediate(function() {
console.log('setImmediate')
});
}, 10);
usa sempre setImmediate, a meno che tu non sia veramente sicuro di averne bisogno setTimeout(,0)(ma non riesco nemmeno a immaginare, per cosa). setImmediateil callback verrà quasi sempre eseguito prima setTimeout(,0), tranne quando viene chiamato al primo tick e al setImmediatecallback.
setTimeoutdovrebbe essere il go-to, con setImmediateusato solo quando dimostrato di essere necessario.
Totalmente insoddisfatto delle risposte fornite. Ho pubblicato quello che penso sia una risposta migliore qui: https://stackoverflow.com/a/56724489/5992714
Domande è un possibile duplicato di Perché il comportamento di setTimeout (0) e setImmediate () è indefinito quando viene utilizzato nel modulo principale?
Penso che la risposta di Navya S non sia corretta, ecco il mio codice di prova:
let set = new Set();
function orderTest() {
let seq = [];
let add = () => set.add(seq.join());
setTimeout(function () {
setTimeout(function () {
seq.push('setTimeout');
if (seq.length === 2) add();
}, 0);
setImmediate(function () {
seq.push('setImmediate');
if (seq.length === 2) add();
});
}, 10);
}
// loop 100 times
for (let i = 0; i < 100; i++) {
orderTest();
}
setTimeout(() => {
// will print one or two items, it's random
for (item of set) {
console.log(item);
}
}, 100);
Le spiegazioni sono qui
setTimeout (fn, 0) può essere utilizzato per impedire il blocco del browser durante un aggiornamento massiccio. ad esempio in websocket.onmessage, potresti avere modifiche html e se i messaggi continuano ad arrivare, il browser potrebbe bloccarsi quando usi setImmidiate
Per capirli a fondo, una volta passare attraverso le fasi del ciclo di eventi.
SetImmediate: viene eseguito nella fase di "verifica". La fase di controllo viene richiamata dopo la fase di I / O.
SetTimeOut: viene eseguito nella fase "timer". La fase del timer è la prima fase ma viene richiamata dopo la fase I / O e dopo il Check fase di .
Per ottenere l'output in modo deterministico, dipenderà da quale fase è il ciclo di eventi; di conseguenza, possiamo usare la funzione su due.
usa setImmediate () per non bloccare il ciclo di eventi. La richiamata verrà eseguita sul ciclo di eventi successivo, non appena quello corrente è terminato.
usa setTimeout () per ritardi controllati. La funzione verrà eseguita dopo il ritardo specificato. Il ritardo minimo è di 1 millisecondo.