我是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;
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.');
我有什么原子性不能得到吗?
但是当我移动var创建&amp;分配,输出完全不同(最终结果为1)。
{{1}}
有什么建议吗?有读物吗?
度过美好的一天!
答案 0 :(得分:1)
来自Bergi提供的外部资源:
所有Javascript事件处理程序脚本都是从一个主事件队列处理的。这意味着事件处理程序一次运行一个,一个运行直到完成,然后下一个准备开始运行。因此,Javascript中没有竞争条件。 javascript中的任何单独执行线程将在下一个启动之前运行完成。
来自this。
并且:
在触发下一个事件之前,一个事件将运行完成。因此,如果在第一次处理仍然处理时发生第二次单击,则第二次单击将排队,并且在处理完第一次的代码完成之前不会运行。
来自that
答案 1 :(得分:0)
当代码启动时,eventemitter最初一次性发出所有事件。因此在启动程序后立即触发on 'event'
。在完成所有事件处理程序注册后,所有超时回调都是仅。在console.log
回调中放入event
(不在settimeout
回调中)并查看输出。
在第二个代码段中,所有settimeout
回调都会捕获count = 0
,因为
var c = count;
在settimeout
回调之外,因此回调将其递增为1.
但是在第一个代码片段计数是在回调中读取的
var c = count;
所以每个回调都有更新的值。