2017-03-01 2 views
0

Nachdem ich viel über NodeJS Ereignisschleife gelesen habe, habe ich noch einen Zweifel.NodeJS Ereignisschleife interne Arbeit

In unserem Code, wenn die NodeJS-Laufzeit einen asynchronen Aufruf findet, wird sie in die Task/Message Queue geschoben, die auf einem Hintergrundthread läuft und V8 unseren weiteren Code im Hauptthread ausführt. Sobald der asynchrone Task beendet ist, überprüft der Knoten den Aufruf-Stack auf leer. Wenn der Aufrufstapel leer ist, dann bringt nur der Knoten diesen Callback zur Verarbeitung zum Hauptthread. Andernfalls muss gewartet werden, bis der Aufrufstapel leer ist.

Bis zu diesem Punkt nehme ich an, ich bin richtig.

Zweifel: Wenn die asynchrone Task beendet ist und der Aufrufstapel nicht leer ist, muss der Callback warten, bis der Aufrufstapel leer ist. Angenommen, es gibt so viele Aufrufe in meinem Aufruf-Stack, die oft dauern (weniger als async-Task zu beenden) und asynchrone Task früher beendet wurde, dann ist es unnötig zu warten, bis der Call-Stack leer wird.

Hat Knoten auf diese Weise nur so entworfen, dass der Callback warten muss, bis der Aufrufstapel leer wird?

Antwort

1

Wenn die asynchrone Task beendet wird und der Aufrufstapel nicht leer ist, muss der Callback warten, bis der Aufrufstapel leer ist. Angenommen, es gibt so viele Aufrufe in meinem Aufruf-Stack, die oft dauern (weniger als async-Task zu beenden) und asynchrone Task früher beendet wurde, dann ist es unnötig zu warten, bis der Call-Stack leer wird.

Das stimmt. Wenn Sie zum Beispiel fs.readFile() aufrufen und dann eine lang andauernde for-Schleife ausführen, muss der Lesevorgang beendet werden, bevor die for-Schleife beendet wird. Sie muss immer noch auf die Schleife for warten.

Zum Beispiel betrachten diesen Code:

let fs = require('fs'); 

fs.readFile(__filename, 'utf-8', (err, data) => { 
    if (err) { 
    console.log('Error:', err.message); 
    } else { 
    console.log(data); 
    } 
}); 

for (let i = 0; i < 1e9; i++); 

Der readFile Rückruf wird warten müssen für die for Schleife zu beenden.

Hat Node auf diese Weise nur so entworfen, dass der Rückruf warten muss, bis der Aufrufstapel leer wird?

Ja. Sie müssen sicherstellen, dass Sie die Ereignisschleife nicht blockieren, indem Sie den Hauptthread mit lang laufenden Berechnungen blockieren, die verhindern, dass der Aufrufstapel leer wird. Dies ist nicht nur Node, so funktioniert auch alles clientseitige JavaScript.

Weitere Details finden Sie diese Antwort: