2016-11-16 49 views
1

尋找找到一種方法來刪除除最近添加的監聽器之外的所有監聽器。刪除除最近添加的所有事件發佈監聽器

所以對於process.stdin,我們可能會做

process.stdin.on('readable',function a(){}); 
process.stdin.on('readable',function b(){}); 
process.stdin.on('readable',function c(){}); 

我想刪除回調a和b,但離開℃。

然而,在這種情況下,我沒有爲A或B的參考,我想要做的事,如:

while(process.stdin.listenerCount('readable') > 1){ 
    process.stdin.removeListener('readable'); 
} 

,但我認爲你需要傳遞一個函數在解決這個辦法。 ?

+1

如果要刪除偵聽器,則必須傳入添加時使用的函數。而且,由於您需要該函數,因此它不能是一個匿名函數 - 它必須是一個在公共範圍內聲明的命名函數,以便在刪除它時添加時具有相同的引用。 – jfriend00

+0

你絕對是對的。看起來很奇怪,如果你調用removeListener('event-name')而沒有函數作爲第二個參數,那麼它不會僅僅彈出陣列中最老的監聽器 –

+0

奇怪?我不這麼認爲。這是一個編碼完整性的東西。如果您沒有對該函數的引用,則不允許刪除該偵聽器。發射器被設計用於許多包括外部代碼,不僅在您自己的代碼中。你可以包裝自己的覆蓋'.on()'來保存監聽器引用,這樣你就可以根據需要使用它們來刪除處理程序。不難實現。 – jfriend00

回答

1

您可以通過eventEmitter.listeners()檢索特定事件的處理程序副本。但是,你真的不應該依賴他們的特定順序。

這裏是一個這樣的解決方案,目前的工作:

process.stdin.listeners('readable').forEach(function(fn) { 
    if (process.stdin.listenerCount('readable') > 1) 
    process.stdin.removeListener('readable', fn); 
}); 

如果你知道你要保持一個函數的名稱,然後就可以,而不只是分支上fn.name代替,如:

process.stdin.listeners('readable').forEach(function(fn) { 
    if (fn.name !== 'c') 
    process.stdin.removeListener('readable', fn); 
}); 

還有一點需要注意的是,如果您從'readable'事件處理程序中刪除這些監聽程序,那麼其他監聽程序仍將針對該特定事件(而不是未來事件)被調用。這是因爲在.emit()期間調用事件名稱的偵聽器之前,它們都被調用。