2012-01-05 2 views
0

Предположим следующий сценарий:Потенциально запирая цикл событий в Node.js через EventEmitter

//Where "e" is a global object in the app 
e = new EventEmitter; 

... 

//at some place in the app code I'm adding Listener 1 
e.on('myEvent', function() {console.log('Listener 1)}); 

... 

//at another place in the app code I'm adding Listener 2 
e.on('myEvent', function() {console.log('Listener 2)}); 

... 

//at another place in the app code I'm adding Listener N 
e.on('myEvent', function() {console.log('Listener N)}); 

... 

//finally in some place I'm emitting "myEvent" 
e.emit('myEvent', p1, p2); 

В тот момент, когда "e.emit ('MyEvent', p1, p2)" выполняется, то мой код, который находится под управлением основного потока узла (а не цикла события). И функция «испускать» является синхронной, поэтому «emit» вызывает в этот самый момент каждого из слушателей, прикрепленных к «myEvent» (в приведенном примере N слушателей). Таким образом, на самом деле, называя «e.emit („MyEvent“, p1, p2)» эквивалентно сделать следующие вызовы в традиционной императивной парадигме:

Listener1(p1,p2); 
Listener2(p1,p2); 
... 
ListenerN(p1,p2); 

И если N велик, я блокирующее цикл события, вызывает его текущий код, который контролирует основной поток, а не цикл событий.

Этот сценарий правдивый и возможен? По этой причине, что по умолчанию Node.js имеет максимум 10 слушателей?

Заранее благодарен!

ответ

1

Поскольку Javascript (без ручного создания дочерних процессов) является однопоточным, все, что вы выполняете в коде, означает, что оно выполняется последовательно. Сам язык синхронный. В случае, если вы используете EventEmitter для добавления слушателей, он все равно выполняет все одно за другим, когда вы их добавляли. Можно удушить узел с пучком ручного извещания, но это то же самое, что и цикл while(true), который будет иметь аналогичный результат. EventEmitter существует, просто чтобы иметь возможность использовать тот же шаблон, что и встроенные модули. Грубый эквивалент EventEmitter будет следующим:

var handlers = []; 

function addHandler(fn) { 
    handlers.push(fn); 
} 

function emit() { 
    for (var i = 0; i < handlers.length; i++) { 
    handlers[i](); 
    } 
} 

// Add a bunch of handlers 
addHandler(function(){console.log('foobar 1');}); 
.... 
addHandler(function(){console.log('foobar N');}); 

// Fire the event 
emit(); 

Асинхронная часть представляет собой сочетание операционной системы и узел, что позволяет делегировать задачи, такие как чтение файла, буферный и т.д. для самой ОС, которая в основном делает это в другом потоке, оставляя Node свободным для запуска цикла событий. Когда ОС запускает событие для узла, что чтение файла завершено, оно затем выполняет необходимые изменения, которые вы написали внутри своего JS. При запуске обработчика заполненного файла все циклы событий все еще останавливаются, так как в любой момент есть один экземпляр выполнения JS.

От documentation:

По умолчанию EventEmitters будет выдавать предупреждение, если более 10 слушатели добавляют к нему. Это полезное значение по умолчанию, которое помогает найти утечки памяти. Очевидно, что не все излучатели должны быть ограничены 10.

Надеюсь, что оно очистило хотя бы что-то.

+0

Спасибо! Это очень ясно! – uyjco0

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