JavaScript ist Single-Threaded und verfügt über ein synchrones Ausführungsmodell. Single Threaded bedeutet, dass jeweils ein Befehl ausgeführt wird. Synchron bedeutet, dass jeweils eine Codezeile ausgeführt wird, damit der Code angezeigt wird. In JavaScript passiert also jeweils eine Sache.
Ausführungskontext
Die JavaScript-Engine interagiert mit anderen Engines im Browser. Im JavaScript-Ausführungsstapel befindet sich unten ein globaler Kontext. Wenn wir dann Funktionen aufrufen, erstellt die JavaScript-Engine neue Ausführungskontexte für die jeweiligen Funktionen. Wenn die aufgerufene Funktion beendet wird, wird ihr Ausführungskontext aus dem Stapel entfernt, und dann wird der nächste Ausführungskontext angezeigt und so weiter ...
Beispielsweise
function abc()
{
console.log('abc');
}
function xyz()
{
abc()
console.log('xyz');
}
var one = 1;
xyz();
Im obigen Code wird ein globaler Ausführungskontext erstellt und in diesem Kontext var one
gespeichert. Sein Wert ist 1 ... Wenn der Aufruf von xyz () aufgerufen wird, wird ein neuer Ausführungskontext erstellt und wenn wir eine Variable definiert haben In der xyz-Funktion würden diese Variablen im Ausführungskontext von xyz () gespeichert. In der xyz-Funktion rufen wir abc () auf und dann wird der Ausführungskontext abc () erstellt und auf den Ausführungsstapel gelegt ... Wenn abc () fertig ist, wird der Kontext vom Stapel entfernt, und der Kontext xyz () wird aus dem Stapel entfernt Stapel und dann wird der globale Kontext gepoppt ...
Nun zu asynchronen Rückrufen; asynchron bedeutet mehr als eine gleichzeitig.
Genau wie beim Ausführungsstapel gibt es die Ereigniswarteschlange . Wenn wir über ein Ereignis in der JavaScript-Engine benachrichtigt werden möchten, können wir dieses Ereignis abhören, und dieses Ereignis wird in die Warteschlange gestellt. Zum Beispiel ein Ajax-Anforderungsereignis oder ein HTTP-Anforderungsereignis.
Wenn der Ausführungsstapel leer ist, wie im obigen Codebeispiel gezeigt, überprüft die JavaScript-Engine regelmäßig die Ereigniswarteschlange und prüft, ob ein Ereignis gemeldet werden muss. In der Warteschlange gab es beispielsweise zwei Ereignisse, eine Ajax-Anforderung und eine HTTP-Anforderung. Es wird auch geprüft, ob es eine Funktion gibt, die für diesen Ereignisauslöser ausgeführt werden muss ... Die JavaScript-Engine wird also über das Ereignis benachrichtigt und kennt die entsprechende Funktion, die für dieses Ereignis ausgeführt werden soll. Die JavaScript-Engine ruft also die auf Handlerfunktion, im Beispielfall, z. B. AjaxHandler (), und wie immer, wenn eine Funktion aufgerufen wird, wird ihr Ausführungskontext in den Ausführungskontext gestellt, und jetzt wird die Funktionsausführung beendet und die Ereignis-Ajax-Anforderung wird ebenfalls aus der Ereigniswarteschlange entfernt ... Wenn AjaxHandler () fertig ist, ist der Ausführungsstapel leer, sodass die Engine die Ereigniswarteschlange erneut überprüft und die Ereignishandlerfunktion der HTTP-Anforderung ausführt, die als nächstes in der Warteschlange stand. Es ist wichtig zu beachten, dass die Ereigniswarteschlange nur verarbeitet wird, wenn der Ausführungsstapel leer ist.
Im folgenden Code wird beispielsweise die Behandlung des Ausführungsstapels und der Ereigniswarteschlange durch die Javascript-Engine erläutert.
function waitfunction() {
var a = 5000 + new Date().getTime();
while (new Date() < a){}
console.log('waitfunction() context will be popped after this line');
}
function clickHandler() {
console.log('click event handler...');
}
document.addEventListener('click', clickHandler);
waitfunction(); //a new context for this function is created and placed on the execution stack
console.log('global context will be popped after this line');
Und
<html>
<head>
</head>
<body>
<script src="program.js"></script>
</body>
</html>
Führen Sie nun die Webseite aus, klicken Sie auf die Seite und sehen Sie die Ausgabe auf der Konsole. Die Ausgabe wird sein
waitfunction() context will be popped after this line
global context will be emptied after this line
click event handler...
Die JavaScript-Engine führt den Code synchron aus, wie im Abschnitt zum Ausführungskontext erläutert. Der Browser stellt die Dinge asynchron in die Ereigniswarteschlange. Daher können die Funktionen, deren Ausführung sehr lange dauert, die Ereignisbehandlung unterbrechen. Dinge, die in einem Browser geschehen, wie Ereignisse, werden auf diese Weise von JavaScript behandelt. Wenn ein Listener ausgeführt werden soll, wird er von der Engine ausgeführt, wenn der Ausführungsstapel leer ist. Und Ereignisse werden in der Reihenfolge verarbeitet, in der sie auftreten. Im asynchronen Teil geht es also darum, was außerhalb der Engine geschieht, dh was die Engine tun soll, wenn diese externen Ereignisse eintreten.
JavaScript ist also immer synchron.