2014-06-09 14 views

Antwort

32

setTimeout ist einfach wie der Aufruf der Funktion, nachdem die Verzögerung beendet ist. Wann immer eine Funktion aufgerufen wird, wird sie nicht sofort ausgeführt, sondern in die Warteschlange gestellt, so dass sie ausgeführt wird, nachdem alle ausführenden und momentan in der Warteschlange befindlichen Eventhandler zuerst fertig sind. setTimeout (, 0) bedeutet im Wesentlichen ausführen, nachdem alle aktuellen Funktionen in der aktuellen Warteschlange ausgeführt wurden. Es kann nicht garantiert werden, wie lange es dauern könnte.

setImmediate ist in dieser Hinsicht ähnlich, außer dass es Warteschlange der Funktionen nicht verwendet. Es prüft die Warteschlange von E/A-Eventhandlern. Wenn alle E/A-Ereignisse im aktuellen Snapshot verarbeitet werden, wird der Rückruf ausgeführt. Es reiht sie sofort nach dem letzten I/O-Handler ein, etwa so wie process.nextTick. So ist es schneller.

Auch (setTimeout, 0) wird langsam, weil es den Timer mindestens einmal vor der Ausführung überprüft. Manchmal kann es doppelt so langsam sein. Hier ist ein Benchmark.

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}) 

Ausgabe

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) 

Zuerst gibt man Idee schnellstmögliche Anrufe. Sie können selbst überprüfen, ob setTimeout halb so oft aufgerufen wird wie andere. Denken Sie auch daran, dass setImmediate an Ihre Dateisystemaufrufe angepasst wird. Unter Last wird es weniger leisten. Ich glaube nicht, dass setTimeout es besser machen kann.

setTimeout ist eine unaufdringliche Art, Funktionen nach einiger Zeit aufzurufen.Es ist genau wie im Browser. Es ist möglicherweise nicht für Serverseite geeignet (denke, warum ich benchmark.js nicht setTimeout verwendet habe).

+0

Es ist wichtig zu beachten, dass setTimeout bei einer fünffachen Verschachtelung einer erzwungenen Verzögerung von mindestens vier Millisekunden unterliegt. [siehe html spec] (https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) –

5

setImmediate() soll die sofortige Ausführung von Callback nach E/A-Ereignissen Rückrufe und vor setTimeout und setInterval planen.

setTimeout() soll die Ausführung eines einmaligen Rückrufs nach einer Verzögerung von Millisekunden einplanen.

Dies ist, was die Dokumente sagen.

setTimeout(function() { 
    console.log('setTimeout') 
}, 0) 

setImmediate(function() { 
    console.log('setImmediate') 
}) 

Wenn Sie den obigen Code ausführen, wird das Ergebnis so sein ... auch wenn die aktuelle doc heißt es, dass nach dem I/O-Ereignisse Rückrufe und vor SetTimeout immediate ‚Ausführung von Callback„, um den Zeitplan‘ und setInterval. " ..

Ergebnis ..

SetTimeout

setImmediate

Wenn Sie Ihr Beispiel in einem anderen Timer wickeln, es durch setTimeout gefolgt immer setImmediate druckt.

setTimeout(function() { 
    setTimeout(function() { 
    console.log('setTimeout') 
    }, 0); 
    setImmediate(function() { 
    console.log('setImmediate') 
    }); 
}, 10); 
+0

Also wann bevorzugen Sie eins über dem anderen? –

+12

Sie haben nicht erklärt, warum was Sie gezeigt haben passiert. Diese Antwort war mir nicht nützlich. –

+2

@Savannah Bitte erläutern Sie in Ihrem ersten Ergebnis, warum setTimeout zuerst ausgeführt wurde, bevor setImmediate –

4

immer setImmediate verwenden, wenn Sie wirklich sicher sind, dass Sie setTimeout(,0) brauchen (aber ich glaube nicht einmal, was für). setImmediate Callback wird fast immer vor setTimeout(,0) ausgeführt, außer beim ersten Tick und setImmediate Callback aufgerufen.

+0

Ich würde sagen, die wichtigsten Grund für die Verwendung von setTimeout anstelle von setImmediate ist, dass Ihr Code von Browsern ausgeführt werden muss, die setmediate nicht implementiert haben. Selbst dann können Sie einfach eine Unterlegscheibe erstellen. –

+1

Das ist unsolide Beratung. Wenn alles danach verlangt, zuerst zu gehen, werden die auftauchenden Leistungsmerkmale der asynchronen Ausführung im Vergleich zur Warteschlange am Ende zu Müll. 'setTimeout' sollte der Einstieg sein, wobei' setImmediate' nur dann verwendet wird, wenn dies notwendig ist. –

-2

Verwenden Sie setImmediate(), um die Ereignisschleife nicht zu blockieren. Der Rückruf wird bei der nächsten Ereignisschleife ausgeführt, sobald die aktuelle ausgeführt wurde.

Verwenden Sie setTimeout() für kontrollierte Verzögerungen. Die Funktion wird nach der angegebenen Verzögerung ausgeführt. Die minimale Verzögerung beträgt 1 Millisekunde.

4

Ein toller Artikel darüber, wie die Ereignisschleife funktioniert und einige Missverständnisse beseitigt. http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/

Unter Berufung auf den Artikel:

setImmediate Rückrufe genannt nach I/O-Queue Rückrufe fertig sind oder Zeitüberschreitung. setUmmediate-Callbacks werden in die Check-Warteschlange gestellt, die nach der E/A-Warteschlange verarbeitet werden.

setTimeout(fn, 0) Callbacks werden in die Timer Queue gestellt und nach I/O Callbacks sowie Check Queue Callbacks aufgerufen. Als Ereignisschleife verarbeiten Sie die Timer-Warteschlange zuerst in jeder Iteration. Welche zuerst ausgeführt wird, hängt davon ab, welche Phasenereignisschleife verwendet wird.

Verwandte Themen