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 bazDieser 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 bazDies 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.