Ich habe gerade die Promises / A + -Spezifikation gelesen und bin auf die Begriffe Mikrotask und Makrotask gestoßen: siehe http://promisesaplus.com/#notes
Ich habe noch nie von diesen Begriffen gehört und bin jetzt gespannt, was der Unterschied sein könnte.
Ich habe bereits versucht, einige Informationen im Web zu finden, aber alles, was ich gefunden habe, ist dieser Beitrag aus dem w3.org-Archiv (der mir den Unterschied nicht erklärt): http://lists.w3.org/Archives /Public/public-nextweb/2013Jul/0018.html
Außerdem habe ich ein npm-Modul namens "macrotask" gefunden: https://www.npmjs.org/package/macrotask Auch hier ist nicht klar, was der Unterschied genau ist.
Ich weiß nur, dass es etwas mit der Ereignisschleife zu tun hat, wie in https://html.spec.whatwg.org/multipage/webappapis.html#task-queue und https: //html.spec.whatwg beschrieben .org / multipage / webappapis.html # perform-a-microtask-checkpoint
Ich weiß, dass ich angesichts dieser WHATWG-Spezifikation theoretisch in der Lage sein sollte, die Unterschiede selbst zu extrahieren. Aber ich bin sicher, dass auch andere von einer kurzen Erklärung eines Experten profitieren könnten.
quelle
while (task = todo.shift()) task();
Antworten:
Bei einem Durchlauf der Ereignisschleife wird genau eine Aufgabe aus der Makrotask-Warteschlange verarbeitet (diese Warteschlange wird in der WHATWG-Spezifikation einfach als Aufgabenwarteschlange bezeichnet ). Nach Abschluss dieser Makrotask werden alle verfügbaren Mikrotasks verarbeitet, und zwar innerhalb desselben Durchlaufzyklus . Während diese Mikrotasks verarbeitet werden, können sie noch mehr Mikrotasks in die Warteschlange stellen, die alle einzeln ausgeführt werden, bis die Mikrotask-Warteschlange erschöpft ist.
Was sind die praktischen Konsequenzen daraus?
Wenn eine Mikrotask andere Mikrotask rekursiv in die Warteschlange stellt, kann es lange dauern, bis die nächste Makrotask verarbeitet wird. Dies bedeutet, dass Sie möglicherweise eine blockierte Benutzeroberfläche oder einen fertigen E / A-Leerlauf in Ihrer Anwendung haben.
Zumindest in Bezug auf die process.nextTick-Funktion von Node.js (die Mikrotasks in die Warteschlange stellt ) gibt es jedoch einen integrierten Schutz gegen eine solche Blockierung mithilfe von process.maxTickDepth. Dieser Wert ist auf den Standardwert 1000 eingestellt, wodurch die weitere Verarbeitung von Mikrotasks nach Erreichen dieses Grenzwerts verringert wird, wodurch die nächste Makrotask ermöglicht wird verarbeitet werden kann.
Wann sollte was verwendet werden?
Verwenden Sie Mikrotasks grundsätzlich, wenn Sie Dinge asynchron synchron ausführen müssen (dh wenn Sie sagen würden, dass Sie diese (Mikro-) Aufgabe in naher Zukunft ausführen müssen ). Ansonsten bleiben Sie bei Makrotasks .
Beispiele
Makrotasks: setTimeout , setInterval , setImmediate , requestAnimationFrame , E / A , UI-Rendering-
Mikrotasks: process.nextTick , Promises , queueMicrotask , MutationObserver
quelle
process.maxTickDepth
wurde vor sehr langer Zeit entfernt: github.com/nodejs/node/blob/…Grundbegriffe in spec :
Das Prozessmodell der Ereignisschleife lautet wie folgt:
Wenn der Aufrufstapel leer ist, führen Sie die folgenden Schritte aus:
Ein vereinfachtes Prozessmodell lautet wie folgt:
etwas zu merken:
quelle
setImmediate()
ist Makro / Aufgabe undprocess.nextTick()
ist ein Mikro / Job.paint
? In welche Kategorie würden sie passen?requestAnimationFrame
)Ich denke, wir können die Ereignisschleife nicht getrennt vom Stapel diskutieren, also:
JS hat drei "Stapel":
Und die Ereignisschleife funktioniert folgendermaßen:
Der Mico-Stack wird nicht berührt, wenn der Stack nicht leer ist. Der Makrostapel wird nicht berührt, wenn der Mikrostapel nicht leer ist ODER keine Ausführung erfordert.
Zusammenfassend lässt sich sagen: Die Mikrotask-Warteschlange entspricht fast der Makrotask-Warteschlange, aber diese Aufgaben (process.nextTick, Promises, Object.observe, MutationObserver) haben eine höhere Priorität als Makrotask.
Mikro ist wie Makro, aber mit höherer Priorität.
Hier haben Sie "ultimativen" Code, um alles zu verstehen.
quelle