2017-04-20 2 views
1

Ich hoffe mein Titel ist korrekt. Ich war heute in einem Interview und war über eine Frage, die sich mit der Event-Schleife/Single Threading beschäftigte, ratlos. Hier ist der Code:Wie blockiert Single Threading DOM-Manipulation in JavaScript?

function longCB(){ 
    for (var i = 0; i <= 9999; i++){ 
    console.log(i); 
    } 
    $('#status').text('hello') 
} 

$('#status').text('hi') 
longCB(); 

Die Frage war, warum zeigt das DOM niemals 'hallo' auf dem #status div? Völlig ratlos erklärte der Interviewer, dass es wegen single threading in Javascript war und erklärte, dass nur durch das Hinzufügen eines setTimeout zu longCB(), selbst wenn es auf 0 gesetzt wurde, es funktionieren würde. Nach der Überprüfung der Event-Loop/Event-Que und Call-Stacks bin ich immer noch völlig ratlos, warum das nicht funktioniert? Sollte nicht die Linie

$('#status').text('hi') 

vor dem Aufruf von longCB() erfolgen? Was vermisse ich? Danke im Voraus.

Antwort

1

Das liegt daran, dass der einzelne Thread auch von der Rendering-Engine des Browsers gemeinsam genutzt wird. Solange JS synchron läuft, wird die Seite auf dem Bildschirm nicht aktualisiert. Warum? Nun, sagen Sie diesen Code haben:

elem.style.color = 'red'; 
elem.style.opacity = '1'; 
elem.textContent = 'Hello'; 

Sie würden nicht das Element wollen den alten Text in rot zeigen, dann machen es undurchsichtig und dann den Text Hallo ändern. Sie möchten nur, dass sich der Text sofort ändert und rot und undurchsichtig ist. Dies ist einer der Gründe, warum das Rendering erst ausgeführt wird, nachdem alle JS ausgeführt wurden. Der andere Grund hat mit der Leistung zu tun. Rendering braucht Zeit!

$('#status').text('hi') 
longCB(); 

Sie sind nicht falsch, wenn Sie sagen, dass der Text zu ‚hallo‘ gesetzt ist, bevor auch longCB() Aufruf, aber da der Faden noch JS läuft, wird die Seite nicht neu gezeichnet bekommen nur noch. Die Verwendung von setTimeout fügt einfach den Methodenaufruf zu einem Stapel von Dingen hinzu, die irgendwann in der Zukunft zu tun sind, und der Browser wird garantiert zwischen dem Ende eines synchronen Skripts und der Verarbeitung von Ereignissen oder Zeitüberschreitungen rendern.

+0

Wow, vielen Dank. Ich schätze es sehr. Ich werde es mehr erforschen, aber könnten Sie möglicherweise erklären, was ein Thread genau ist? Ist ein einzelner Thread ein Blockumfang pro sagen? – user1842315

+1

Ich habe gerade Philip Roberts Keynote über Event-Loop gesehen. https://www.youtube.com/watch?v=8aGhZQkoFbQ Ich weiß jetzt, dass es eine Render-Queue gibt, die nur ausgeführt werden kann, wenn der Call-Stack frei ist. Da longCB() im Aufruf-Stack ist, rendert der Browser #status nie mit dem Text 'hi'. Vielen Dank – user1842315

+0

Ein Thread oder Prozess in einer Programmiersprache bedeutet normalerweise einen einzelnen "Cursor", der sich durch den Code bewegt, im Gegensatz zu mehreren gleichzeitig ablaufenden Code-Teilen. Verwechseln Sie nicht, Thread kann sich auch auf einen vom Betriebssystem verwalteten Speicherblock und Prozessorzeit beziehen. Beispielsweise hat Chrome für jede Registerkarte einen anderen Prozess, wie im Task-Manager zu sehen ist. Prozessoren können mehrere Kerne haben, die manchmal als Threads bezeichnet werden. Es ist ein sehr lockerer Begriff, um darüber nachzudenken. –