2015-04-29 60 views
0

因此,目前正在研究一个应用程序,它可以完成相当多的数据库工作,并且认为解决此问题的一个聪明方法应该是使用事件。因此,我为应用程序设置了一个事件发射器,然后将其用作控制流的方法。我认为事件发射器的作用类似于消息队列或类似的东西。奇怪的行为编码事件

事实并非如此,由于某种原因,我无法使第二次调用同一个函数时偶数发射器正常工作。

我会明白,如果问题是它会多次调用,但是因为它是,下面的代码将运行第二个函数两次,但只会得到一次通过dbEvents.once('Ready'。而且不仅我不知道为什么,好像这个工作不断,绝不会打印出“中写道四”

var mongo = require('mongodb'); 
var events = require('events'); 
var dbEvents = new events.EventEmitter(); 




function writeStuff(first, second, status, cuID){ 
     console.log('Wrote '+ first); 
     if (status === 1) { 
      console.log('\t\tReady for '+ cuID); 
      dbEvents.emit('Ready'); 
     } else { 
      console.log('\t\tReady (but not 1) for ' + cuID); 
      dbEvents.emit('Ready'); 
     } 
     console.log('\t\tjust about to kick of number ' + status); 
     dbEvents.once('Ready', function (condata) { 
      console.log('Wrote '+ second) 
      dbEvents.emit('Done'+cuID) 

     }); 

} 

var cuID1 = mongo.ObjectID(); 
writeStuff('First', 'Second', 1, cuID1); 
dbEvents.on('Done'+cuID1, function(){ 
    console.log('\tFirst completed ' + cuID1); 
}); 

var cuID2 = mongo.ObjectID(); 
writeStuff('Third', 'Forth', 2, cuID2); 

dbEvents.on('Done'+cuID2, function(){ 
    console.log("\tSecond completed " + cuID2) 
}); 

var b = 0; 
for(var i = 0; i < 100000000; i++){ 
    b++; 
} 
console.log("And I counted to " + b); 

当我运行上面的代码看起来像这样

Wrote First 
       Ready for 5540c57cd8fa9555076f9aba 
       just about to kick of number 1 
Wrote Third 
       Ready (but not 1) for 5540c57cd8fa9555076f9abb 
Wrote Second 
     First completed 5540c57cd8fa9555076f9aba 
       just about to kick of number 2 
And I counted to 100000000 
输出

================ UPDATE ==============

为什么我不能生成事件,IE如果我使用唯一的标识符,它似乎不能将它作为事件发送。在这种情况下,我将事件更改为Ready + cuID(mongodb),现在第二次写入不会被调用。

var mongo = require('mongodb'); 
var events = require('events'); 
var dbEvents = new events.EventEmitter(); 




function writeStuff(first, second, status, cuID){ 
     console.log('Wrote '+ first); 
     if (status === 1) { 
      console.log('\t\tReady for '+ cuID); 
      var flag = 'Ready'+cuID 
      dbEvents.emit(flag); 
     } else { 
      console.log('\t\tReady (but not 1) for ' + cuID); 
      dbEvents.emit('Ready'); 
     } 
     console.log('\t\tjust about to kick of number ' + status); 
     dbEvents.once(flag, function (condata) { 
      console.log('Wrote '+ second) 
      dbEvents.emit('Done'+cuID) 

     }); 

} 

var cuID1 = mongo.ObjectID(); 
writeStuff('First', 'Second', 1, cuID1); 
dbEvents.on('Done'+cuID1, function(){ 
    console.log('\tFirst completed ' + cuID1); 
}); 

var cuID2 = mongo.ObjectID(); 
writeStuff('Third', 'Forth', 2, cuID2); 

dbEvents.on('Done'+cuID2, function(){ 
    console.log("\tSecond completed " + cuID2) 
}); 

var b = 0; 
for(var i = 0; i < 1000000000; i++){ 
    b++; 
} 
console.log("And I counted to " + b); 

回答

1

看来你要添加的“准备”听众调度后第一次运行“就绪”事件。现在,当你开始第二次运行时,第一个侦听器将被调用。这解释了为什么'写第二'被记录'写第三'被称为。

将侦听器添加到writeStuff()的开头。

function writeStuff(first, second, status, cuID){ 

    console.log('\t\tjust about to kick of number ' + status); 
    dbEvents.once('Ready', function (condata) { 
     console.log('Wrote '+ second) 
     dbEvents.emit('Done'+cuID) 

    }); 

    console.log('Wrote '+ first); 
    if (status === 1) { 
     console.log('\t\tReady for '+ cuID); 
     dbEvents.emit('Ready'); 
    } else { 
     console.log('\t\tReady (but not 1) for ' + cuID); 
     dbEvents.emit('Ready'); 
    } 

} 
+0

非常感谢你江户。这确实可以解决这个问题,但对于顺序调用函数的更大问题没有帮助,但我仍然遇到第一个调用执行两个步骤的问题,第二个迭代只调用第一个调用。 – vrghost

+0

嘿,我没有看到你正在尝试实现更新的代码示例。有几个问题:1)在调用“标志”事件后,您似乎将侦听器添加到“标志”(请参阅​​此答案)。 2)你最终想通过循环实现什么? 看起来你可能不知道所有这些代码都会同步运行,这就是为什么如果在你分派事件之后添加**,你的监听器将不会被调用。 – Edo