setImmediate()
verstehen
Wenn Sie ein Stück Code asynchron, aber so schnell wie möglich ausführen möchten, ist eine Option die Verwendung der von Node.js bereitgestellten Funktion setImmediate()
:
setImmediate(() => {
// etwas tun
})
Jede Funktion, die als Argument an setImmediate()
übergeben wird, ist ein Callback, der in der nächsten Iteration der Event-Loop ausgeführt wird.
Wie unterscheidet sich setImmediate()
von setTimeout(() => {}, 0)
(Übergabe eines 0-ms-Timeouts) und von process.nextTick()
und Promise.then()
?
Eine an process.nextTick()
übergebene Funktion wird in der aktuellen Iteration der Event-Loop ausgeführt, nachdem die aktuelle Operation beendet ist. Das bedeutet, dass sie immer vor setTimeout
und setImmediate
ausgeführt wird.
Ein setTimeout()
-Callback mit einer Verzögerung von 0 ms ist setImmediate()
sehr ähnlich. Die Ausführungsreihenfolge hängt von verschiedenen Faktoren ab, aber beide werden in der nächsten Iteration der Event-Loop ausgeführt.
Ein process.nextTick
-Callback wird zur process.nextTick-Warteschlange hinzugefügt. Ein Promise.then()
-Callback wird zur Microtask-Warteschlange für Promises hinzugefügt. Ein setTimeout
- oder setImmediate
-Callback wird zur Macrotask-Warteschlange hinzugefügt.
Die Event-Loop führt zuerst Aufgaben in der process.nextTick-Warteschlange aus, dann die Microtask-Warteschlange für Promises und dann die Macrotask-Warteschlange für setTimeout
oder setImmediate
.
Hier ist ein Beispiel, um die Reihenfolge zwischen setImmediate()
, process.nextTick()
und Promise.then()
zu zeigen:
const baz = () => console.log('baz');
const foo = () => console.log('foo');
const zoo = () => console.log('zoo');
const start = () => {
console.log('start');
setImmediate(baz);
new Promise((resolve, reject) => {
resolve('bar');
}).then(resolve => {
console.log(resolve);
process.nextTick(zoo);
});
process.nextTick(foo);
};
start();
// start foo bar zoo baz
Dieser Code ruft zuerst start()
auf, dann foo()
in der process.nextTick-Warteschlange. Danach wird die Microtask-Warteschlange für Promises behandelt, die bar ausgibt und gleichzeitig zoo()
in der process.nextTick-Warteschlange hinzufügt. Dann wird zoo()
aufgerufen, das gerade hinzugefügt wurde. Am Ende wird baz()
in der Macrotask-Warteschlange aufgerufen.
Das oben genannte Prinzip gilt in CommonJS-Fällen, aber denken Sie daran, dass in ES-Modulen, z. B. mjs
-Dateien, die Ausführungsreihenfolge unterschiedlich ist:
// start bar foo zoo baz
Dies liegt daran, dass das geladene ES-Modul als asynchrone Operation verpackt ist und somit das gesamte Skript bereits in der Microtask-Warteschlange für Promises ist. Wenn das Promise also sofort aufgelöst wird, wird sein Callback an die Microtask-Warteschlange angehängt. Node.js wird versuchen, die Warteschlange zu leeren, bevor zu einer anderen Warteschlange übergegangen wird, und daher wird die Ausgabe zuerst bar angezeigt.