【发布时间】:2017-11-04 09:35:52
【问题描述】:
我不是在谈论复杂的比赛条件involving the network 或events。相反,我似乎发现 += 运算符在 V8(Chrome 58 或 Node 8)中不是原子的。
下面的代码旨在并行运行两个所谓的线程。每个“线程”重复调用一个函数,该函数在sleeping 那么多秒后返回其数字参数。结果是summed up 进入累加器。
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Return the passed number after sleeping that many seconds
async function n(c) {
await sleep(c * 1000);
console.log('End', c);
return c;
}
let acc = 0; // global
// Call n repeatedly and sum up results
async function nForever(c) {
while (1) {
console.log('Calling', c);
acc += await n(c); // += not atomic?!
console.log('Acc', acc);
}
}
(async function() {
// parallel repeated calls
nForever(1);
nForever(5.3); // .3 for sanity, to avoid overlap with 1 * 5
})();
问题是,大约 5 秒后,我希望累加器为 10.3(5 乘以 1 + 1 乘以 5.3)。但是,它是 5.3!
【问题讨论】:
-
我很好奇实现是如何在幕后进行的,也许在 await 语句期间创建了一个闭包,该语句存储了 await 调用时当前范围内的所有变量。有趣的是,这两个函数似乎完全独立地增加了 acc,就像它们将 acc 放在本地范围而不是全局范围中一样
标签: javascript node.js multithreading asynchronous async-await