2016-06-28 18 views
7

In den offiziellen Websites von NodeJS (https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg) aufgerufen wird, wird gesagt, dass:setImmediate() Funktion nach Funktion setTimeout()

setImmediate() Funktion Pläne "sofort" Durchführung von Rückruf nach I/Es werden die Rückrufe von O-Ereignissen und vor den von setTimeout gesetzten Timern und setInterval ausgelöst.

Im folgenden Code jedoch setTimeout() -Funktion vor setImmediate() ausgeführt. Warum?

setImmediate(function A() { 
    setImmediate(function B() { 
    console.log(1); 
    setImmediate(function D() { console.log(2); }); 
    setImmediate(function E() { console.log(3); }); 
    }); 
    setImmediate(function C() { 
    console.log(4); 
    setImmediate(function F() { console.log(5); }); 
    setImmediate(function G() { console.log(6); }); 
    }); 
}); 

setTimeout(function timeout() { 
    console.log('TIMEOUT FIRED'); 
}, 0) 

Ergebnis:

 
TIMEOUT FIRED 
1 
4 
2 
3 
5 
6 

Ich schreibe ein weiteres Beispiel, und setTimeout Werke vor setImmediate auch hier.

setTimeout(function timeout() { 
    console.log('TIMEOUT-1 FIRED'); 
}, 0) 

setTimeout(function timeout() { 
    console.log('TIMEOUT-2 FIRED'); 
}, 0) 

setImmediate(function D() { console.log(1); }); 
setImmediate(function D() { console.log(2); }); 
setImmediate(function D() { console.log(3); }); 

setTimeout(function timeout() { 
    console.log('TIMEOUT-1 FIRED'); 
}, 0) 

setTimeout(function timeout() { 
    console.log('TIMEOUT-2 FIRED'); 
}, 0) 

Output:

 
TIMEOUT-1 FIRED 
TIMEOUT-2 FIRED 
TIMEOUT-1 FIRED 
TIMEOUT-2 FIRED 
1 
2 
3 
+0

In Node 5.6.0 für die erste, die ich '1 4 TIMEOUT 2 3 5 6' – Pointy

+0

FIRED erhalten @metis, welche Version von node.js sind Sie verwenden, da es scheint, ein Bug mit einigen älteren Versionen: https://github.com/nodejs/node-v0.x-archive/issues/6034 –

+0

v.4.4.5 es ist empfohlene Version für die meisten Benutzer auf der Willkommensseite von nodejs – metis

Antwort

1

Läßt das obige Beispiel wie folgt schreiben:

var fs = require('fs') 

fs.readFile("readme.txt", function(){ 
    setTimeout(function timeout() { 
     console.log('TIMEOUT-1 FIRED'); 
    }, 0) 

    setTimeout(function timeout() { 
     console.log('TIMEOUT-2 FIRED'); 
    }, 0) 

    setImmediate(function D() { console.log(1); }); 
    setImmediate(function D() { console.log(2); }); 
    setImmediate(function D() { console.log(3); }); 

    setTimeout(function timeout() { 
     console.log('TIMEOUT-1 FIRED'); 
    }, 0) 

    setTimeout(function timeout() { 
     console.log('TIMEOUT-2 FIRED'); 
    }, 0)}) 

Output:

1 
2 
3 
TIMEOUT-1 FIRED 
TIMEOUT-2 FIRED 
TIMEOUT-1 FIRED 
TIMEOUT-2 FIRED 

Erläuterung:

Die Reihenfolge, in der die Timer ausgeführt werden, hängt vom Kontext ab, in dem sie aufgerufen werden. Wenn beide aus dem Hauptmodul aufgerufen werden, ist die Zeitplanung an die Leistung des Prozesses gebunden (die von anderen Anwendungen beeinflusst werden kann, die auf dem Computer ausgeführt werden). Wenn wir beispielsweise das folgende Skript ausführen, das sich nicht in einem E/A-Zyklus befindet (dh das Hauptmodul), ist die Reihenfolge, in der die beiden Timer ausgeführt werden, nicht deterministisch, da es an die Leistung des Prozess:

// timeout_vs_immediate.js 
setTimeout(function timeout() { 
    console.log('timeout'); 
},0); 

setImmediate(function immediate() { 
    console.log('immediate'); 
}); 
$ node timeout_vs_immediate.js 
timeout 
immediate 

$ node timeout_vs_immediate.js 
immediate 
timeout 

wenn Sie jedoch die beiden Anrufe innerhalb eines E/A-Zyklus bewegen, wird die sofortige Rückruf immer zuerst ausgeführt:

// timeout_vs_immediate.js 
var fs = require('fs') 

fs.readFile(__filename,() => { 
    setTimeout(() => { 
    console.log('timeout') 
    }, 0) 
    setImmediate(() => { 
    console.log('immediate') 
    }) 
}) 
$ node timeout_vs_immediate.js 
immediate 
timeout 

$ node timeout_vs_immediate.js 
immediate 
timeout 

der Hauptvorteil setImmediate mit () über setTimeout() wird setImmediate() wird immer vor allen Timern ausgeführt, wenn sie innerhalb eines E/A-Zyklus geplant werden, unabhängig davon, wie viele Timer vorhanden sind.

Weitere Informationen finden Sie auf den folgenden Link: https://github.com/nodejs/node/blob/master/doc/topics/the-event-loop-timers-and-nexttick.md

+0

Es beschreibt nur, was in der Hauptdokumentation geschrieben, die nicht klar ist, wie es funktioniert, wie es an die Leistung gebunden ist? Was bedeutet "an die Leistung gebunden" Das ist die Hauptfrage. – hsafarya

Verwandte Themen