2015-04-29 120 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