Was ist im Kontext von serverseitigen Javascript-Engines nicht blockierende E / A oder asynchrone E / A. Ich sehe dies als einen Vorteil gegenüber serverseitigen Java-Implementierungen.
Was ist im Kontext von serverseitigen Javascript-Engines nicht blockierende E / A oder asynchrone E / A. Ich sehe dies als einen Vorteil gegenüber serverseitigen Java-Implementierungen.
Antworten:
Die synchrone Ausführung bezieht sich normalerweise auf Code, der nacheinander ausgeführt wird. Asynchrone Ausführung bezieht sich auf die Ausführung, die nicht in der Reihenfolge ausgeführt wird, in der sie im Code angezeigt wird. Im folgenden Beispiel bewirkt der synchrone Betrieb, dass die Warnungen nacheinander ausgelöst werden. Während der asynchronen Operation alert(2)
die zweite Ausführung ausgeführt wird, ist dies nicht der Fall.
Synchron: 1,2,3
alert(1);
alert(2);
alert(3);
Asynchron: 1,3,2
alert(1);
setTimeout(() => alert(2), 0);
alert(3);
Das Blockieren bezieht sich auf Operationen, die die weitere Ausführung blockieren, bis diese Operation abgeschlossen ist. Nicht blockierend bezieht sich auf Code, der die Ausführung nicht blockiert. In dem angegebenen Beispiel localStorage
handelt es sich um eine Blockierungsoperation, da die Ausführung zum Lesen blockiert wird. Auf der anderen Seite fetch
handelt es sich um eine nicht blockierende Operation, da die alert(3)
Ausführung nicht blockiert wird .
// Blocking: 1,... 2
alert(1);
var value = localStorage.getItem('foo');
alert(2);
// Non-blocking: 1, 3,... 2
alert(1);
fetch('example.com').then(() => alert(2));
alert(3);
Ein Vorteil nicht blockierender asynchroner Vorgänge besteht darin, dass Sie die Nutzung einer einzelnen CPU sowie des Arbeitsspeichers maximieren können.
Ein Beispiel für synchrone Blockierungsvorgänge ist die Verarbeitung von E / A- oder Netzwerkanforderungen durch einige Webserver wie in Java oder PHP. Wenn Ihr Code aus einer Datei oder der Datenbank liest, "blockiert" Ihr Code alles, was danach ausgeführt wird. In diesem Zeitraum hält Ihr Computer an Speicher und Verarbeitungszeit für einen Thread fest , der nichts tut .
Um andere Anforderungen zu erfüllen, während dieser Thread blockiert ist, hängt dies von Ihrer Software ab. Die meisten Server-Software-Programme erzeugen mehr Threads, um die zusätzlichen Anforderungen zu erfüllen. Dies erfordert mehr Speicherverbrauch und mehr Verarbeitung.
Asynchrone, nicht blockierende Server - wie die in Node erstellten - verwenden nur einen Thread, um alle Anforderungen zu bearbeiten. Dies bedeutet, dass eine Instanz von Node das Beste aus einem einzelnen Thread herausholt. Die Entwickler haben es mit der Prämisse entworfen, dass die E / A- und Netzwerkoperationen der Engpass sind.
Wenn Anforderungen auf dem Server eintreffen, werden sie einzeln bearbeitet. Wenn der zu wartende Code beispielsweise die Datenbank abfragen muss, sendet er den Rückruf an eine zweite Warteschlange und der Hauptthread wird weiter ausgeführt (er wartet nicht). Wenn der DB-Vorgang abgeschlossen ist und zurückkehrt, wird der entsprechende Rückruf aus der zweiten Warteschlange gezogen und in eine dritte Warteschlange gestellt, in der die Ausführung aussteht. Wenn die Engine die Möglichkeit erhält, etwas anderes auszuführen (z. B. wenn der Ausführungsstapel geleert wird), nimmt sie einen Rückruf aus der dritten Warteschlange auf und führt ihn aus.
var startTime = new Date().getTime();
var getEndTime = () => {
var tempEndTime = new Date().getTime();
var second = (tempEndTime - startTime)/1000
return `took ${second} sec...to finish\n`
}
console.log('1: start App', getEndTime())
setTimeout(()=>{
console.log('2: setTimeout', getEndTime())
}, 1000)
console.log('3: End App', getEndTime())
// console -> Process Order: 1 -> 3 -> 2