Вызов .on() перед .emit() в эмиттере событий, есть ли проблема со временем?

Возьмите этот код, где f — это поток с «телом» события, который вызывает слушателей с m, который сам является потоком, излучающим события:

f.on('message', function(m) {
  m.on('body', function(stream, info) {
    var b = '';
    stream.on('data', function(d) {
      b += d;
    });
    stream.on('end', function() {
      if (/^header/i.test(info.which))
        msg.header = Imap.parseHeader(b);
      else
        msg.body = b;
    });
  });
  m.on('attributes', function(attrs) {
    msg.attrs = attrs;
    msg.contentType = partID[1];
  });
});
f.on('end', function() {
  if (hadErr)
    return;
  cb(undefined, msg);
});

Серверная часть генерирует событие «сообщение», передавая ему объект m. Затем код прослушивает события body и attributes. Все просто, за исключением того, что мой маленький мозг находится в некотором кризисе (я не привык иметь дело с потоками). В частности: как бэкенд излучает объекты f и m, чтобы гарантировать, что события действительно вызываются в нужное время?

Конкретно:

  • Как должен быть закодирован f в общих чертах, чтобы гарантировать, что mm не будет излучать до тех пор, пока не будет вызван m.on('body', function(stream, info) {?
  • Нужно ли добавлять прослушиватель с помощью on() до события, чтобы его можно было перехватить?
  • Если да, значит ли это, что f и m будут генерировать события после регистрации кода здесь?
  • Если предполагается, что серверная часть гарантирует, что b.emit('end') вызывается после m.emit('end'), как это вообще должно произойти на самом деле, по-прежнему гарантируя, что on() вызывается before любое из событий излучается?

ОК, я на 100% запутался в этом вопросе. Я явно упускаю что-то основное и важное, и из-за этого я даже не могу задать правильные вопросы...! (Извинения)


person Merc    schedule 29.09.2014    source источник


Ответы (1)


Нужно ли добавлять прослушиватель с помощью on() до того, как событие будет отправлено, чтобы его можно было поймать?

Да.

Если да, значит ли это, что f и m будут генерировать события после того, как код здесь зарегистрируется?

Нет, события нигде не ставятся в очередь. Если их никто не слушает, они пропадут. Я думаю, это то, о чем вы все равно спрашиваете... f и m, похоже, не генерируют события в вашем коде.

Если бэкэнд должен гарантировать, что b.emit('end') вызывается после m.emit('end'), то как это вообще должно произойти на самом деле, по-прежнему гарантируя, что on() вызывается до любого из события испускаются?

b - это строка в вашем примере? Я не уверен, что вы спрашиваете здесь.

Подумайте об этом по-другому. Когда вызывается .on, функция подписывается на канал сообщений. Эти сообщения уже передаются до того, как эта функция будет подписана, и будут продолжать передаваться, если эта функция не подписана. .on и .removeListener() просто устанавливают статус подписки для конкретной функции.

События могут создаваться, даже если их никто не прослушивает. События могут запускаться все время, и если их никто не слушает, они просто никуда не пойдут. (Исключением являются события ошибок, встроенные в Node.js, которые превращаются в настоящие исключения, если нет обработчика ошибок.)

Как должен быть закодирован f в общих чертах, чтобы гарантировать, что mm не будет испускать до тех пор, пока не будет вызвано m.on('body', function(stream, info) {?

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

Вы можете запутаться в порядке обработки событий для новых объектов. В Node.js есть правило... Никогда не испускать напрямую из вашего конструктора. Всегда используйте nextTick() или подобное. Таким образом, после создания экземпляра любой код для присоединения к обработчикам событий может сделать это до того, как события будут отправлены.

Кроме того, если вы используете потоки, рассмотрите возможность использования события readable, чтобы поток оставался приостановленным до тех пор, пока вы не будете готовы его прочитать. Тянуть против толкать.

person Brad    schedule 29.09.2014
comment
Спасибо, Брэд! Разобравшись во всем этом... Я добавил вопрос! Я думаю, что я сужаюсь, где мое замешательство! Вопрос: How would f have to be coded, in general terms, in order to make sure that mm doesn't emit till m.on('body', function(stream, info) { is called? (Но, пожалуйста, обновите свой ответ, а не отвечайте здесь, я хочу принять ваш ответ как ответ!) - person Merc; 29.09.2014