2016-04-30 2 views
0

Поскольку значение «порядка» широка, позвольте мне объяснить случай, я заинтересован вEventEmitter упорядочения событий

довольно общий шаблон (хорошо или плохо).

client = net.connect(...) 
client.on('connect',() => { 
    client.removeAllListeners('error'); 
    client.on('error', err => { 
    ... // process IO errors 
    }); 
    ... 
}); 
client.on('error', err => { 
    ... // process connection failures 
}); 

так, как я понять, что это работает, возможно, что событие connect испускается, а затем выдается IO error. Но есть ли гарантия на уровне EventEmitter, что обработка событий действует как барьер (в соответствующей параллельной речи программирования).

Например, в этом случае я хотел бы получить гарантию, что обработчик connect удалит обработчик error, установленный только для ошибок подключения, и новый обработчик, настроенный только для ошибок ввода-вывода. Но будет ли учитываться список новых слушателей событий только во время следующего тика? Я хочу быть уверенным, что взаимно исключенные обработчики в программном порядке (параллельная речь программирования: «removeAllListeners» и «on (« error »)» выполняются в этом порядке, поэтому для обоих обработчиков невозможно получить одно и то же событие) также взаимно исключенные в порядке синхронизации (параллельное программирование речи: события «connect», «removeAllListeners», «on» (error) »и« ошибка ввода-вывода »являются частью общего порядка синхронизации).

Вопрос об эмитенте событий вообще, а не о том, как работает обработка соединения, поскольку аналогичный шаблон можно увидеть в других местах - например, одно и то же соединение, используемое для обработки разных транзакций, и необходимо связать обработчик error на время отдельных транзакций, но не может позволить себе перекрывать обработчики или обрабатывать события после транзакции.

Есть ли такая гарантия в EventEmitter? В противном случае многие шаблоны, подобные выше, действительно должны кодироваться гораздо более защитно.

ответ

0

Ни один из методов EventEmitter не откладывает до следующего тика или чего-то еще, все они выполняют всю свою работу в момент их вызова.

Таким образом, client.removeAllListeners('error'); немедленно удалит все обработчики событий для события error.

+0

Но есть также случай «очереди событий», имеющей более одного события в очереди. Есть ли гарантия, как именно они стоят в очереди? Например, во время выхода события его обработчики помещаются в очередь - это означает, что если несколько событий могут быть выпущены за один тик, обработчики будут выставлены в очередь для выполнения, прежде чем они будут удалены одним из обработчиков. –

+0

Дело в точке: 'e.on ('a', x => {e.removeAllListeners ('a'); e.on ('a', y => console.log ('y =' + y);); console.log ('x =' + x);}); e.emit ('a', 0); e.emit ('a', 1); '- конечно, удаление прослушивателей имело немедленный эффект, но не так для добавления слушателя - второй слушатель не получает событие 0, поэтому не все имеет немедленный эффект. –

+0

Это другой сценарий. Если вы добавляете/удаляете прослушиватели для определенного события из * внутри * обработчика событий для этого же события, то он не будет действовать до следующего 'emit()' для этого конкретного события. 'emit()' сначала копирует прослушиватели событий, чтобы предотвратить различные проблемы, включая циклы/циклы. Даже при этом до сих пор нет явного отсрочки до следующего тика или позже в любой из функций EventEmitter. – mscdex

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