Join devRant
Do all the things like
++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatar
Sign Up
Pipeless API

From the creators of devRant, Pipeless lets you power real-time personalized recommendations and activity feeds using a simple API
Learn More
Related Rants
:headache:
Reading a JS book. Came across the following classic race condition problem that reminds me of my college lessons on async programming and threading. It sure is a headache.
Thanking A.I. for explaining it to me further, because I was thinking that the value kept being updated with each fileName once resolved, but no:
async function fileSizes(files) {
let list = "";
await Promise.all(files.map(async fileName => {
list += fileName + ": " + (await textFile(fileName)).length + "\n";
}));
return list;
}
Problem:
1. list starts as an empty string.
2. For each fileName, you create an async function (inside map) that does:
list += fileName + ": " + (await textFile(fileName)).length + "\n";
3. Because all the async functions are launched at once (via Promise.all), they all reach their await quickly, and at that moment they all “remember” the same initial value of list (the empty string).
4. Then, whichever async call resolves last will overwrite list with its update. The previous writes get clobbered, since each one applied += to the old snapshot (""), not the already-updated string.
A.I.: Why is this a problem?
The root cause is mutating shared state (list) across async boundaries. Because += is not atomic, each async task doesn’t “see” the other updates — they all start from the same baseline.
Solution:
async function fileSizes(files) {
const lines = await Promise.all(files.map(async fileName => {
const length = (await textFile(fileName)).length;
return fileName + ": " + length;
}));
return lines.join("\n");
}
Each async task just computes its own independent result string. No shared state, no race condition.
Book lesson: computing a new value (though more expensive) is often less error prone than changing existing values (bindings in this case).
College lesson: remember that operations on a computer are not atomic. You always have things like the ALU, the registers and the values in between. Oh great, now I am reminded of atomicity in database transactions. :barfs: lol
Useful lessons. This is why Computer Science fundamentals are important. :)
rant
race-conditions
async
javascript