JavaScript ist single-threaded, solange Du keine Webworker einsetzt und keine Requeste auf externe Dienste machst. Innerhalb deines JS wirst Du keine race condition erhalten.
Ich halte dir zu Gute, dass wir zeitgleich geantwortet haben, und du meine Antwort daher noch nicht gelesen haben konntest. Trotzdem, muss ich das gleich nochmal korriegeren: JavaScript hat Race-Conditions. Einfaches Beispiel: https://jsfiddle.net/017my4wz/8/. Drückt man den Button wiederholt mit mehr als einer halben Sekunde Abstand, dann inkremintiert der Counter wie gewollt. Wartet man nicht so lange zwischen den Klicks, dann tritt eine Race-Condition auf und der Counter zählt falsch. Ausschlaggebend dafür ist, dass bei jedem Klick und jedem Timeout ein neuer Task in die Event-Queue gepusht wird und die Tasks greifen auf die geteilte Variable i
zu. Die Tasks greifen konkurrierend auf die geteilte Zählvariable i
zu.