Die Event-Schleife von Node.js wirkt mysteriös, bis Sie aufhören, sie als eine einzige Warteschlange zu betrachten.
Es gibt mehrere Warteschlangen und mehrere Prioritäten, und der verwirrendste Teil für viele Ingenieure ist, dass Mikrotasks nicht dasselbe sind wie die Haupt-Phase-Schleife von libuv.
Ein Nützliches Mentales Modell
Dieses Skript ist ein guter Ausgangspunkt:
setTimeout(() => console.log("timeout"), 0);
setImmediate(() => console.log("immediate"));
Promise.resolve().then(() => console.log("promise"));
process.nextTick(() => console.log("nextTick"));
console.log("sync");
Die wichtigen Konzepte sind:
- synchroner Code läuft zuerst
process.nextTick wird vor anderen Mikrotasks in Node ausgeführt
- Promises-Rückrufe werden ausgeführt, bevor die Event-Schleife zu späteren Phasen übergeht
- Timer und
setImmediate gehören zu unterschiedlichen späteren Phasen
Deshalb ist process.nextTick so mächtig und so leicht zu missbrauchen.
Warum nextTick Ihnen Schaden Zufügen Kann
Wenn Sie rekursiv mehr nextTick-Arbeiten planen, können Sie I/O hungern, da Node diese Warteschlange weiterhin abarbeitet, bevor es fortfährt.
Deshalb sollte nextTick sparsam eingesetzt werden.
Wenn Sie ein wenig warten müssen, damit die Event-Schleife weiterhin den Prozess bedienen kann, ist setImmediate oft das gesündere Werkzeug.
Der Ingenieurtechnische Wert
Das ist keine Interview-Trivia.
Es ist wichtig, wenn Sie:
- Latenzspitzen diagnostizieren
- merkwürdige Rückrufreihenfolgen debuggen
- versuchen, I/O-Hungern zu vermeiden
Die Event-Schleife fühlt sich nicht mehr magisch an, sobald Sie in Warteschlangen und Planungspunkten denken, anstatt zu glauben, dass "asynchrone Codes später ausgeführt werden".
Weiterführende Lektüre