我是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;
因此,每个回调都具有更新的值。