2012-05-17 62 views
4

以下是我的代碼的NodeJS事件的NodeJS處理

var emitter = require('events'), 
    eventEmitter = new emitter.EventEmitter(); 
eventEmitter.on('data', function (result) { console.log('Im From Data'); }); 

eventEmitter.on('error', function (result) { console.log('Im Error'); }); 

require('http').createServer(function (req, res) { 
    res.end('Response'); 
    var start = new Date().getTime(); 
    eventEmitter.emit('data', true); 
    eventEmitter.emit('error', false); 
    while(new Date().getTime() - start < 5000) { 
     //Let me sleep 
    } 

    process.nextTick(function() { 
     console.log('This is event loop'); 
    }); 
}).listen(8090); 

是的NodeJS單線程的,它在一個事件循環運行,並在同一個線程服務的事件。 因此,在上面的代碼中,對我的本地主機:8090節點線程的請求應該保持忙於爲請求提供服務[有5秒的睡眠時間]。

同時有兩個事件由eventEmitter發出。因此,這兩個事件都必須在事件回調中排隊等待請求處理完成。

但是,這並沒有發生,我可以看到發出的同時發生的事件。

這是預期的嗎?我明白,如果它按我期望的那樣工作,那麼就不會使用擴展事件模塊。但eventEmitter發出的事件是如何處理的?

+0

只是猜測你正在報告什麼...它似乎像eventEmitter.emit同步處理(而不是異步)。這意味着他們從來沒有在事件隊列中排隊...... FWIW,這是我一直在java中實現所有監聽器/事件模式的方式。所以這似乎是振振有詞的正確行爲 – ControlAltDel

回答

7

只有需要異步處理的東西被推入事件循環。節點中的標準事件發射器將立即發送事件。只有使用諸如process.nextTick,setTimeout,setInterval之類的代碼或在C++中明確添加的代碼纔會影響事件循環,如節點的庫。

例如,當您將節點的fs庫用於createReadStream之類的東西時,它會返回一個流,但會在後臺打開該文件。當它打開時,節點將添加到事件循環中,並且當循環中的函數被調用時,它將觸發流對象上的'open'事件。然後,節點將在後臺加載文件中的塊,並添加到事件循環中以觸發流上的data事件。

如果您希望在5秒後發出這些事件,您希望在忙循環後使用setTimeout或撥打emit

我還想說清楚,你不應該像Node代碼那樣有一個繁忙的循環。我不知道你是否只是在測試事件循環,或者它是否是一些真實代碼的一部分。如果您需要更多信息,請詳細說明您希望實現的功能。

+0

我100%確定我不應該阻止事件回覆。這只是我寫的一個測試代碼,用於理解行爲:)感謝您的解釋:)還可以詳細說明'將代碼明確地添加到C++'部分,這樣我就可以100%清楚並接受答案 – Tamil

+0

酷。我已經更新了我的答案。 – loganfsmyth