In most other languages, your newScore() example would indeed race as you claim, but in JS it actually won't. JS uses a single-threaded event loop, meaning asynchronous things like timers going off and keys being pressed pile up in a queue until the currently executing call stack finishes, and are only processed then.<p>In your example, this means profile.score will remain at 3 every time. Interestingly this would still be the case even if setTimeout() was replaced with Promise.resolve(), since the sole "await" desugars to ".then(rest-of-the-function)", and handlers passed to .then() are always added to the job queue, even if the promise they are called on is already settled [0].<p>To fix this (i.e., introduce an actual race), it would be enough to add a single "await" sometime after the call to newScore(), e.g., "await doSomethingElse()" (assuming doSomethingElse() is async). That would cause the final "profile.score" line to appear in the job queue at some indeterminate time in the future, instead of executing immediately.<p>[0]: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objec1ts/Promise#:~:text=An%20action%20can%20be%20assigned%20to%20an%20already%20settled%20promise.%20In%20this%20case%2C%20the%20action%20is%20added%20immediately%20to%20the%20back%20of%20the%20job%20queue%20and%20will%20be%20performed%20when%20all%20existing%20jobs%20are%20completed" rel="nofollow">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...</a>