Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中具有复合赋值的竞争条件_Javascript_Node.js_Multithreading_Asynchronous_Async Await - Fatal编程技术网

JavaScript中具有复合赋值的竞争条件

JavaScript中具有复合赋值的竞争条件,javascript,node.js,multithreading,asynchronous,async-await,Javascript,Node.js,Multithreading,Asynchronous,Async Await,我不是在说复杂的比赛条件或比赛。相反,我似乎已经发现+=操作符在V8(Chrome58或Node8)中不是原子的 下面的代码旨在并行运行两个所谓的线程。每个“线程”重复调用一个函数,该函数在数秒后返回其number参数。结果存入累加器 功能睡眠(毫秒){ 返回新承诺(resolve=>setTimeout(resolve,ms)); } //睡眠数秒后返回传递的数字 异步函数n(c){ 等待睡眠(c*1000); console.log('End',c); 返回c; } 设acc=0;//全球

我不是在说复杂的比赛条件或比赛。相反,我似乎已经发现
+=
操作符在V8(Chrome58或Node8)中不是原子的

下面的代码旨在并行运行两个所谓的线程。每个“线程”重复调用一个函数,该函数在数秒后返回其number参数。结果存入累加器

功能睡眠(毫秒){
返回新承诺(resolve=>setTimeout(resolve,ms));
}
//睡眠数秒后返回传递的数字
异步函数n(c){
等待睡眠(c*1000);
console.log('End',c);
返回c;
}
设acc=0;//全球的
//反复调用n并总结结果
异步函数nForever(c){
而(1){
console.log('Calling',c);
acc+=等待n(c);//+=不是原子的?!
控制台日志(“Acc”,Acc);
}
}
(异步函数(){
//并行重复呼叫
nForever(1);
nForever(5.3);//.3以保持理智,避免与1*5重叠

})();事实上,在将
acc+=wait n(c)
行替换为以下内容后:

const ret = await n(c); acc += ret;
避免了比赛条件

我猜V8没有在包含
acc
的内存位置上将
acc+=await n(c)
优化为
n()
结果的一部分,而是将其扩展为
acc=acc+await n(c)nForever(5.3)
时,
acc
的初始值为0


这对我来说是违反直觉的,虽然不确定V8开发者会认为它是一个bug。

< P>这不是一个竞赛条件,因为你明确地使用<代码>等待Actudio< < /C> >执行< < /P> 该标准定义了复合赋值(如
+=
)不是原子赋值:复合赋值的左侧在右侧之前求值。[]

因此,如果您的RHS以某种方式更改
acc
,这些更改将被覆盖。最简单的例子:

var n=1;
n+=(函数(){
n=2;
返回0;
})();

控制台日志(n)我很好奇实现是如何在幕后进行的,可能是在等待语句期间创建了一个闭包,该语句存储了在等待调用时当前在范围内的所有变量。看到这两个函数似乎都完全独立地增加了acc,这让人很困惑,就像它们将acc放在了本地范围而不是全局范围一样有趣的是,如果我通过babeljs网站转换您的原始代码,它实际上是按照您的预期工作的,5.3秒后给出10.3,表示指向标准。这表明我的错误(准确地说,被第5步打断)。