I\'m not talking about complex race conditions involving the network or events. Rather, I seem to have found out that the +=
operator is not atomic in V8 (Chrome 58
This is not a race condition, because you are explicitly yielding the execution using await
.
The standard defines that a compound assignment such as +=
is not atomic: The left-hand-side of a compound assignment is evaluated before the right-hand-side.[1]
So if your RHS changes acc
somehow, the changes will be overwritten. Most simple example:
var n = 1;
n += (function () {
n = 2;
return 0;
})();
console.log(n);
Indeed, after replacing the acc += await n(c)
line with:
const ret = await n(c); acc += ret;
the race condition was avoided.
My guess is V8 didn't optimize acc += await n(c)
to an ADD of the n()
result over the memory location containing acc
, but rather expanded it to acc = acc + await n(c);
, and the initial value of acc
when nForever(5.3)
was first called, was 0.
This is counter-intuitive to me, though not sure the V8 developers would consider it a bug.