EventEmitter.emitの振る舞い

イベント機構([emit](https://nodejs.org/api/events.html#events_emitter_emit_event_arg1_arg2) -> [on](https://nodejs.org/api/events.html#events_emitter_on_event_listener))を提供する [EventEmitter](https://nodejs.org/api/events.html) の [emit](https://nodejs.org/api/events.html#events_emitter_emit_event_arg1_arg2) / [on](https://nodejs.org/api/events.html#events_emitter_on_event_listener) 挙動について頭の整理＆備忘の為にまとめます。
尚、ここでは、[EventEmitter](https://nodejs.org/api/events.html) である [process](https://nodejs.org/api/process.html) さんを利用して動作確認をしています。

# 単純に [emit](https://nodejs.org/api/events.html#events_emitter_emit_event_arg1_arg2) -> [on](https://nodejs.org/api/events.html#events_emitter_on_event_listener)した場合

emitの実行処理内で、単純に[on](https://nodejs.org/api/events.html#events_emitter_on_event_listener)に登録されたcallbackがコールされます。
その為、on処理中に同emitを処理したい場合などは注意が必要です。実装によっては、再帰処理になる可能性があります。

~~~javascript:process_emit.js
process.on('msg', function(message) {
  console.log(message);
});

console.log('--- before emit msg');
process.emit('msg', 'foo');
console.log('--- after  emit msg');

// $ node process_emit.js
// --- before called emit msg
// foo
// --- after  called emit msg
// $ 
~~~

# [emit](https://nodejs.org/api/events.html#events_emitter_emit_event_arg1_arg2)を [process.nextTick](https://nodejs.org/api/process.html#process_process_nexttick_callback) 又は [setImmediate](https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg) でラップした場合

[process.nextTick](https://nodejs.org/api/process.html#process_process_nexttick_callback) 又は [setImmediate](https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg) でラップすると、次のTick処理で処理がなされ、前述の様な挙動を避けることが可能です。

* [process.nextTick](https://nodejs.org/api/process.html#process_process_nexttick_callback)を利用([gist](https://gist.github.com/gitseitanaka/53e936f6d415da56f79e#file-process_emit_nexttick-js))

~~~javascript:process_emit_nextTick.js
process.on('msg', function(message) {
  console.log(message);
});

console.log('--- before called emit msg');
process.nextTick(function(){
  process.emit('msg', 'foo');
});
console.log('--- after  called emit msg');

// $ node process_emit_nextTick.js
// --- before called emit msg
// --- after  called emit msg
// foo
// $
~~~

* [setImmediate](https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg)を利用([gist](https://gist.github.com/gitseitanaka/53e936f6d415da56f79e#file-process_emit_setimmediate-js))

~~~javascript:process_emit_setImmediate.js
process.on('msg', function(message) {
  console.log(message);
});

console.log('--- before called emit msg');
setImmediate(function(){
  process.emit('msg', 'foo');
});
console.log('--- after  called emit msg');

// $ node process_emit_setImmeiate.js
// --- before called emit msg
// --- after  called emit msg
// foo
// $
~~~

尚、 [process.nextTick](https://nodejs.org/api/process.html#process_process_nexttick_callback) 又は [setImmediate](https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg) の違いは、メインループ内での動作タイミングがの同ループ内のIO確認の「前」or「後」であることですが、詳細は、本ページの記載の際に参考にさせていただいた、以下をご参照ください(非常に勉強になりました)。

  * http://d.hatena.ne.jp/jovi0608/20140320/1395294325
  * http://jxck.hatenablog.com/entry/for-with-eventloop