Die asynchrone Natur von JavaScript kann sich wie Magie anfühlen, bis Sie in die Mechanik eintauchen. Das Geheimnis liegt in der Ereignisschleife, die zwei Hauptakteure orchestriert: Mikrotasks und Makrotasks. Aber was sind sie, wie funktionieren sie und warum sind sie wichtig? Lassen Sie uns das Geheimnis mit einem tiefen Einblick, Beispielen und Tipps zur Beherrschung dieses Konzepts lüften.
Die JavaScript-Engine führt Code in einem einzelnen Thread aus. Um asynchrone Vorgänge abzuwickeln, ist es auf die Ereignisschleife angewiesen, die die Koordination zwischen dem Aufrufstapel und den Aufgabenwarteschlangen übernimmt. Diese Aufgabenwarteschlangen sind in zwei Kategorien unterteilt: Mikroaufgaben und Makroaufgaben.
Mikrotasks sind Aufgaben mit hoher Priorität, die ausgeführt werden müssen, sobald der aktuell ausgeführte JavaScript-Code beendet ist und der Aufrufstapel leer ist. Sie sorgen für schnelle Folgemaßnahmen und konsistente Zustände. Häufige Beispiele sind:
Makrotasks sind Aufgaben mit niedrigerer Priorität, die von der Ereignisschleife erst verarbeitet werden, nachdem alle Mikrotasks ausgeführt wurden. Sie kümmern sich um größere, verzögerte Vorgänge und externe Ereignisse. Häufige Beispiele sind:
Es gibt auch requestAnimationFrame, der nicht Teil einer der beiden Warteschlangen ist. Es synchronisiert sich mit dem Rendering-Zyklus des Browsers und ist somit ideal für flüssige Animationen.
So verarbeitet die Ereignisschleife Aufgaben:
Diese Priorisierung stellt sicher, dass Aufgaben mit hoher Priorität wie Versprechen vor weniger dringenden Vorgängen wie Timern erledigt werden.
Unten finden Sie einen praktischen Codeausschnitt zur Veranschaulichung der Interaktion zwischen synchronem Code, Mikrotasks, Makrotasks und requestAnimationFrame:
console.log('Synchronous code starts'); // Macrotask: setTimeout setTimeout(() => { console.log('Macrotask: setTimeout'); }, 0); // Macrotask: setInterval const intervalId = setInterval(() => { console.log('Macrotask: setInterval'); clearInterval(intervalId); }, 100); // Microtask: Promise Promise.resolve().then(() => { console.log('Microtask: Promise then 1'); Promise.resolve().then(() => { console.log('Microtask: Promise then 2'); }); }); // Microtask: MutationObserver const observer = new MutationObserver(() => { console.log('Microtask: MutationObserver'); }); const targetNode = document.createElement('div'); observer.observe(targetNode, { attributes: true }); targetNode.setAttribute('data-test', 'true'); // Macrotask: MessageChannel const channel = new MessageChannel(); channel.port1.onmessage = () => { console.log('Macrotask: MessageChannel'); }; channel.port2.postMessage('Test'); // requestAnimationFrame requestAnimationFrame(() => { console.log('Outside task queues: requestAnimationFrame'); }); console.log('Synchronous code ends');
Die Ausgabereihenfolge hilft, die Priorisierung zu verdeutlichen:
Obwohl requestAnimationFrame nicht Teil der Aufgabenwarteschlangen ist, spielt es eine einzigartige Rolle bei der Asynchronität. Es plant die Ausführung des Codes vor dem nächsten Browser-Repaint und sorgt so für minimale Frame-Drops und flüssigere Animationen.
Das Zusammenspiel zwischen Mikrotasks, Makrotasks und der Ereignisschleife ist das Herzstück der Asynchronität von JavaScript. Wenn Sie diese Konzepte verstehen und nutzen, können Sie effizienteren, wartbareren und leistungsfähigeren Code schreiben. Denken Sie daran: Mikrotasks zuerst, Makrotasks zweitens und requestAnimationFrame für den visuellen Feinschliff. Viel Spaß beim Codieren!
Das obige ist der detaillierte Inhalt vonTiefer Einblick in die Asynchronität: Mikrotasks, Makrotasks und die Ereignisschleife. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!