dein Beispiel zeigt handgemachtes, kooperatives Multitasking mit Hilfe einer externen Ressource (die Event Queue). Und du "rettest" einen globalen Wert vorsätzlich über einen Thread-Wechsel hinweg. Ts ts ts... 😉
Das Beispiel ist zugegeben eher pathalogischer Natur, das ist dem Umstand geschuldet, dass ich ein poentiertes, nachvollziehbares Beispiel finden wollte. Aber das heißt nicht, dass solche Fälle in der Praxis nicht auch auftreten. Beispiel aus dem Forum, davon ließen sich hier bestimmt auch hundert weitere Threads finden.
Unter einer Race-Condition verstehe ich, dass zwei Programmsegmente echt parallel laufen und man nicht weiß wer zuerst fertig ist.
Ich verstehe eure Erklärungsversuche auch, aber ich erinnere mich auch noch an eine meine eigene Zeit als Anfänger und wie sehr ich mich damals von der Thematik rund um Multi-Threading, Parallelität und Concurrency habe verwirren lassen. Rückwirkend weiß ich, dass das zum Teil auch am schwammigen Gebrauch des Vokabulars gelegen haben muss. Das möchte ich Pit und unseren anderen AnfängerInnen gerne ersparen, deswegen mahne ich das an. Ich glaube mir wäre in vielen Fällen geholfen gewesen, wenn man mir komplizierte Dinge, wie Race Conditions, nicht mit einem intuitivem, aber fachlich ungenauem Sprachgebrauch erklärt hätte. Das hat mich oft auf falsche Fährten gelockt, deshalb plädiere ich hier für den präzisen Einsatz der Fachsprache. In diesem Fall musste das Stichwort ergo Concurrency und nicht Parallelität oder Multi-Threading lauten.
Die für JavaScript wichtige Erkenntnis ist aber: Ein JavaScript-Programm wird in Zyklen ausgeführt. Jeder Zyklus beginnt mit der Entnahme eines Auftrags aus der Event-Queue. Und dann wird er durchlaufen, von Anfang bis Ende, ohne Unterbrechung. Er kann weitere Aufträge in die Event-Queue einstellen, die werden dann später ausgeführt. Funktionen wie setTimeout oder fs.readJson hinterlassen Einträge in der Event-Queue, mal direkt, mal indirekt. Innerhalb eines Zyklus gibt es keine Race-Condition. Wenn logische Abläufe über mehrere Zyklen gehen, dann schon.
Das fasst die Arbeitsweise des Event-Loops gut zusammen.