2016-11-16 2 views
1

Необходимо найти способ удалить всех слушателей, кроме последнего добавленного слушателя.Удалить все прослушиватели-эмитенты событий, кроме последних

Так process.stdin, мы могли бы сделать

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

Я хочу, чтобы удалить обратные вызовы а и б, но оставить с.

Однако, в данном случае у меня нет ссылки на а или б, я хочу сделать что-то вроде:

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

, но я думаю, что вам нужно передать функцию в любом случае вокруг этого. ?

+1

Если вы хотите удалить слушателей, вы должны передать функцию, которая была использована, когда она была добавлена. И поскольку вам нужна функция, она не может быть анонимной функцией - она ​​должна быть именованной функцией, объявленной в общей области, поэтому у вас есть такая же ссылка при ее удалении, как при ее добавлении. – jfriend00

+0

Ты определенно прав. Кажется странным, что если вы вызываете removeListener ('event-name') без функции в качестве второго аргумента, то он не просто вытащит старейшего слушателя из массива –

+0

Weird? Я так не думаю. Это целостность кода. Если у вас нет ссылки на функцию, вам не удастся удалить слушателя. Излучатели предназначены для использования многими, включая внешний код, не только внутри вашего собственного кода. Вы можете обернуть собственное переопределение для '.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().

Смежные вопросы