在事件处理程序中读取和写入全局变量:何时并发是一个问题?



我是Node的新手.JS我开始阅读有关Node.js事件处理和并发性的几个主题。

后面的代码位触发 1000 次事件,这是通过递增全局变量来处理的。第一位代码成功计数为 1000,但第二位甚至不会增加到 2。有没有我没有得到的原子性?

我仍然想知道为什么以下代码提供连贯的输出(它在没有任何并发的情况下成功计数到 1000:

// Import events module
var events = require('events');
// Event emitter
var eventEmitter = new events.EventEmitter();
var max = 1000;
var count = 0;
eventEmitter.on('event', () => {
let time = Math.trunc(Math.random() * 1000) +1;
setTimeout(() => {  
var c = count;
c++;
count = c;
console.log(c);  
}, time);
});
// Fire
for (let i = 0; i < max; i++) {
eventEmitter.emit('event');
}
console.log('Program Ended.');

有没有我没有得到的原子性?

但是当我移动var创建和分配时,输出完全不同(最终结果是1(。

// Import events module
var events = require('events');
// Event emitter
var eventEmitter = new events.EventEmitter();
var max = 1000;
var count = 0;
eventEmitter.on('event', () => {
let time = Math.trunc(Math.random() * 1000) +1;
var c = count;
setTimeout(() => {  
c++;
count = c;
console.log(c);  
}, time);
});
// Fire
for (let i = 0; i < max; i++) {
eventEmitter.emit('event');
}
console.log('Program Ended.');

有什么建议吗?任何阅读 ?

有好的一天!

来自Bergi提供的外部资源:

所有 Javascript 事件处理程序脚本都从一个主事件队列处理。这意味着事件处理程序一次运行一个,一个运行直到完成,然后下一个准备好开始运行的事件处理程序。因此,Javascript中没有竞争条件。javascript 中的任何单个执行线程都将在下一个执行线程开始之前运行完成。

由此。

和:

一个事件将在触发下一个事件之前运行完成。因此,如果在第一次单击仍在处理时发生第二次单击,则第二次单击将排队,并且在代码处理完成第一次单击之前不会运行。

由此

事件发射器最初在代码启动时一次性发出所有事件。因此on 'event'在启动程序后立即触发。 只有在完成所有事件处理程序注册后,才会调用所有超时回调。在 onevent回调(而不是在settimeout回调中(中放置一个console.log并查看输出。

在第二个代码段中,所有settimeout回调都捕获count = 0因为

var c = count;

settimeout回调之外,因此回调将其递增为 1。

但是在第一个代码片段计数是在回调中读取

var c = count; 

因此,每个回调都具有更新的值。

最新更新