Javascript is single threaded but it is not by any means immue to race conditions. Below is a swiss army knife of ways to deal with race conditions.
Single process
- In memory queues
- Mutexes
Multi process
UPDATE
commands- Queues
- Optimistic locking
- FS lock
- Database transactions
In the priveledged scenario that you've only got one process, my favourite way to deal with race conditions is to use an in memory queue to serialize operations. Here's one I made earlier: https://gist.github.com/mfbx9da4/406145db83c4142720754bdab1e2f125
You can use a pessimistic locking type strategy, where you acquire a lock over some resource before using it. A solution for just single process applications. https://gist.github.com/surma/57e48e3e7b267b527ad1bee941b78087
The easiest way to avoid race conditions in multiprocess systems is to let the database handle it for you.
e.g. in SQL UPDATE table_name SET column1 = value1 WHERE condition;
.
A common strategy with data processing is to use a distributed queues e.g. SQS or redis based queues.
A common strategy with NoSQL databases is to implement optimistic locking where writes only succeed if the row's version has not changed.
A fun edge case if you're working with files is to use this hack for locking a file. https://gist.github.com/mfbx9da4/b60edd7143a386c2f4be49b57eb5445b
Database transactions often use pessimistic two phase locking. Transactions are super convenient but relatively costly for the db.