SlideShare a Scribd company logo
Event Loop & EventEmitter
simen
simenkid@gmail.com
github.com/simenkid
Materials
• Demo Code
▫ https://github.com/simenkid/talks
• Read More…
▫ https://simeneer.blogspot.tw/2016/09/nodejs-eventemitter.html
Is Node.js Single Threaded?
• Let’s run a simple http server
var http = require('http');
var server = http.createServer(function (req, res) {
// Request Handler
});
server.listen(3000);
“… Actually only your ‘userland’ code runs in one thread.
… Node.js in fact spins up a number of threads.”
- D. Khan, “How to track down CPU issues in Node.js”
01_server.js
Concurrency
“Concurrency is a way to structure a thing so that you can, maybe, use
parallelism to do a better job. But parallelism is not the goal of
concurrency; concurrency's goal is a good structure.”
- R. Pike, Golang co-inventor
TCP
Server
TCP
Server
Tasks spread over threads Tasks spread over time
Requests
Requests
t
t
Blocking and Non-Blocking I/O
• Simplified concepts of
▫ Blocking I/O
▫ Non-blocking I/O
• I/O multiplexing
▫ Reactor
▫ select() or poll()
▫ Event notification, synchronous event demux
Reactor Pattern
Event Queue
Event Demux
(i.e., select()
CallbackI/O Request
register() Callback Execution
Reactor
Non-Blocking I/O Engine
• libuv
▫ Node.js, Luvit, …
▫ multi-platform support library with a focus on
asynchronous I/O
http://docs.libuv.org/
Linux OSX, BSDs SunOS Windows
Phases In the Loop
┌───────────────────────┐
┌─>│ timers │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ I/O callbacks │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ idle, prepare │
│ └──────────┬────────────┘ ┌───────────────┐
│ ┌──────────┴────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └──────────┬────────────┘ │ data, etc. │
│ ┌──────────┴────────────┐ └───────────────┘
│ │ check │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
└──┤ close callbacks │
└───────────────────────┘
uv__run_timers()
uv__run_pending()
uv__run_idle()
uv__run_prepare()
uv__io_poll()
uv__run_check()
uv__run_closing_handles()
libuv core.c
int uv_run(uv_loop_t* loop, uv_run_mode mode) {
// ...
r = uv__loop_alive(loop);
// ...
while (r != 0 && loop->stop_flag == 0) {
uv__update_time(loop);
uv__run_timers(loop);
ran_pending = uv__run_pending(loop);
uv__run_idle(loop);
uv__run_prepare(loop);
timeout = 0;
if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
timeout = uv_backend_timeout(loop);
uv__io_poll(loop, timeout);
uv__run_check(loop);
uv__run_closing_handles(loop);
if (mode == UV_RUN_ONCE) {
uv__update_time(loop);
uv__run_timers(loop);
}
r = uv__loop_alive(loop);
// ...
} https://github.com/libuv/libuv/blob/v1.x/src/unix/core.c#L332-L372
core.c
Event Loop in Node.js (I)
// Entry point for new node instances, ...
static void StartNodeInstance(void* arg) {
// ...
{
SealHandleScope seal(isolate);
bool more;
do {
v8::platform::PumpMessageLoop(default_platform, isolate);
more = uv_run(env->event_loop(), UV_RUN_ONCE);
if (more == false) {
v8::platform::PumpMessageLoop(default_platform, isolate);
EmitBeforeExit(env);
// Emit `beforeExit` if the loop became alive either after emitting
// event, or after running some callbacks.
more = uv_loop_alive(env->event_loop());
if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
more = true;
}
} while (more == true);
}
// ...
}
node.cc
Event Loop in Node.js (II)
Environment* CreateEnvironment(
Isolate* isolate,
uv_loop_t* loop,
// ...
const char* const* exec_argv)
{
// ...
uv_check_init(env->event_loop(), env->immediate_check_handle());
uv_unref(
reinterpret_cast<uv_handle_t*>(env->immediate_check_handle()));
uv_idle_init(env->event_loop(), env->immediate_idle_handle());
uv_prepare_init(env->event_loop(), env->idle_prepare_handle());
uv_check_init(env->event_loop(), env->idle_check_handle());
uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_prepare_handle()));
uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_check_handle()));
// Register handle cleanups
env->RegisterHandleCleanup(
reinterpret_cast<uv_handle_t*>(env->immediate_check_handle()),
HandleCleanup,
nullptr);
// ...
return env;
}
node.cc
Each node instance has its own event loop.
Put Tasks/Callbacks To Event Loop
• Non-blocking I/O APIs
▫ fs.readFile(path, cb)
• Timer Phase
▫ setTimeout(cb, time)
▫ setInterval(cb, time)
• Check Phase
▫ setImmediate(cb)
• At Each Phase End
▫ process.nextTick(cb)
▫ Microtasks (Promise)
┌───────────────────────┐
┌─>│ timers │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ I/O callbacks │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ idle, prepare │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ poll │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ check │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
└──┤ close callbacks │
└───────────────────────┘
process.nextTick()
Microtasks
[ ]
“Each phase has a FIFO queue of callbacks to execute.”
How Long a Tick Is?
“This is a tick: the synchronous invocation of zero or more callback
functions associated with any external events. Once the queue is
emptied out and the last function returns, the tick is over.”
- josh3736, “What exactly is a Node.js event loop tick?” Answered@stackoverflow
┌───────────────────────┐
┌─>│ timers │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ I/O callbacks │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ idle, prepare │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ poll │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ check │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
└──┤ close callbacks │
└───────────────────────┘
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
I/O Starvation
function crazy() {
console.log('Are you crazy?');
process.nextTick(function () {
crazy();
});
}
crazy();
[ ]
[ ]
[ ]
crazy()
nextTickQueue
“ … any time you call process.nextTick() in a given phase, all callbacks
passed to process.nextTick() will be resolved before the event loop
continues. … "starve" your I/O by making recursive process.nextTick()
calls, …”
EventEmitter
EventEmitter
function EventEmitter() {
EventEmitter.init.call(this);
}
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
// ...
EventEmitter.init = function() {
// ...
if (!this._events || this._events === Object.getPrototypeOf(this)._events) {
this._events = {};
this._eventsCount = 0;
}
this._maxListeners = this._maxListeners || undefined;
};
The base class accommodates Observer Pattern in Node.js
(Publish/Subscribe, Mediator Patterns)
events.js
APIs
EventEmitter.prototype.setMaxListeners
EventEmitter.prototype.getMaxListeners
EventEmitter.prototype.emit (publish)
EventEmitter.prototype.addListener (subscribe)
EventEmitter.prototype.on = EventEmitter.prototype.addListener
EventEmitter.prototype.once
EventEmitter.prototype.removeListener
EventEmitter.prototype.removeAllListeners
EventEmitter.prototype.listeners
EventEmitter.prototype.listenerCount
events.js
.on( )
EventEmitter.prototype.addListener = function addListener(type, listener) {
var m;
var events;
var existing;
if (typeof listener !== 'function')
throw new TypeError('listener must be a function');
events = this._events;
// ...
if (!existing) {
// Optimize the case of one listener.
// Don't need the extra array object.
existing = events[type] = listener;
++this._eventsCount;
} else {
if (typeof existing === 'function') {
// Adding the second element, need to change to array.
existing = events[type] = [existing, listener];
} else {
// If we've already got an array, just append.
existing.push(listener);
}
// ...
}
return this;
};
event_name1: [ ]
event_name3: [ ]
event_name2:
events.js
.emit( )
EventEmitter.prototype.emit = function emit(type) {
// ...
events = this._events;
// ...
handler = events[type];
if (!handler)
return false;
// ...
switch (len) {
// fast cases
case 1:
emitNone(handler, isFn, this);
break;
case 2:
emitOne(handler, isFn, this, arguments[1]);
break;
// ...
// slower
default:
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
emitMany(handler, isFn, this, args);
}
// ...
return true;
};
function emitMany(handler, isFn, self, args) {
if (isFn)
handler.apply(self, args);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].apply(self, args);
}
}
event_name1: [ ]
event_name3: [ ]
event_name2:
events.js
Quick Demo
Who Prints First?
console.log('<0> schedule with setTimeout in 1-sec');
setTimeout(function () { console.log('[0] setTimeout in 1-sec boom!'); }, 1000);
console.log('<1> schedule with setTimeout in 0-sec');
setTimeout(function () { console.log('[1] setTimeout in 0-sec boom!'); }, 0);
console.log('<2> schedule with setImmediate');
setImmediate(function () { console.log('[2] setImmediate boom!'); });
console.log('<3> A immediately resolved promise');
aPromiseCall().then(function () { console.log('[3] promise resolve boom!'); });
console.log('<4> schedule with process.nextTick');
process.nextTick(function () { console.log('[4] process.nextTick boom!'); });
function aPromiseCall () {
return new Promise(function(resolve, reject) { return resolve(); });
}
What if these things are arranged in an I/O callback?
02_prints.js
EventEmitter - Dead Loop
var EventEmitter = require('events');
var crazy = new EventEmitter();
crazy.on('event1', function () {
console.log('event1 fired!');
crazy.emit('event2');
});
crazy.on('event2', function () {
console.log('event2 fired!');
crazy.emit('event3');
});
crazy.on('event3', function () {
console.log('event3 fired!');
crazy.emit('event1');
});
crazy.emit('event1');
event1
event2event3
Synchronous Execution Loop
What if scheduled with…
• process.nextTick()
• setImmediate()
03_deadloop.js
Long-Running Tasks?
• How to deal with my long-running tasks?
▫ Cut it down or use a worker
• A ridiculous heavy task
function doHeavy () {
// Counts how many 1s occurred
var count = 0;
for (var i = 0; i < 1e8; i++) {
if (Math.round(Math.log(
Math.sqrt(Math.abs(Math.round(Math.random() * 1000)))
)) === 1)
count++;
}
return count;
}
setInterval(function () { console.log('I am not blocked'); }, 1000);
console.log(doHeavy()); // Takes around 10 seconds on my machine
04_heavy.js
Cut It Down (I)
function doNotSoHeavy (times) {
var count = 0;
for (var i = 0; i < times; i++) {
if (Math.round(Math.log(
Math.sqrt(Math.abs(Math.round(Math.random() * 1000)))
)) === 1)
count++;
}
return count;
}
function doHeavy() {
var total = 1e8,
cuts = 100,
counts = 0;
for (var i = 0; i < cuts; i++) {
counts = counts + doNotSoHeavy(total/cuts);
}
return counts;
}
setInterval(function () { console.log('I am not blocked'); }, 1000);
console.log(doHeavy()); // Takes around 10 seconds on my machine
Synchronous. Blocks?
04_heavy_cut_sync.js
Cut It Down (II)
function doHeavy(callback) {
var total = 1e8,
cuts = 100,
counts = 0,
remains = cuts;
for (var i = 0; i < cuts; i++) {
setImmediate(function () {
counts = counts + doNotSoHeavy(total/cuts);
remains--;
if (!remains) {
process.nextTick(function () {
callback(counts);
});
}
});
}
}
doHeavy(function (counts) {
console.log(counts);
});
Need a callback to get the asynchronous result
Asynchronous. Blocks?
04_heavy_cut_async1.js
Cut It Down (III)
function doHeavy(callback) {
var total = 1e8,
cuts = 100,
counts = 0,
remains = cuts;
function doPerLoopIter() {
setImmediate(function () {
counts = counts + doNotSoHeavy(total/cuts);
remains--;
if (!remains) {
process.nextTick(function () {
callback(counts);
});
} else {
doPerLoopIter();
}
});
}
doPerLoopIter();
}
doHeavy(function (counts) {
console.log(counts);
});
Asynchronous. Blocks?
04_heavy_cut_async2.js
Cut It Down (IV)
var heavyJobs = {
counts: 0,
queue: [],
_callback: null,
add: function (task) {
this.queue.push(task);
},
next: function (callback) {
var self = this,
task = this.queue.shift();
if (!task) return;
setImmediate(function () {
self.counts = self.counts + task();
if (self.queue.length === 0)
self._callback(self.counts);
else
self.next();
});
},
do: function (callback) {
this._callback = callback;
this.next();
}
};
var total = 1e8,
cuts = 100;
for (var i = 0; i < cuts; i++) {
heavyJobs.add(function () {
return doNotSoHeavy(total/cuts);
});
}
setInterval(function () {
console.log('I am not blocked');
}, 1000);
heavyJobs.do(function (counts) {
console.log(counts);
});
There are many ways to make your
heavy jobs happy…
04_heavy_queue.js
This example is for demonstrating
the idea. Not very thoughtful.
Run With Another Process
var fork = require('child_process').fork;
function doHeavyWithWorker(callback) {
var worker = fork('./heavy_jobs.js');
worker.once('message', function (counts) {
callback(counts);
});
}
setInterval(function () {
console.log('I am not blocked');
}, 1000);
doHeavyWithWorker(function (result) {
console.log(result.counts);
});
// heavy_jobs.js
function doHeavy () {
// Counts how many 1s occurred
var count = 0;
for (var i = 0; i < 1e8; i++) {
if (Math.round(Math.log(
Math.sqrt(Math.abs(
Math.round(Math.random() * 1000))
)
)) === 1)
count++;
}
return count;
}
var counts = doHeavy();
process.send({
counts: counts
});
fork() establishes the IPC channel between parent and child for your convenience to
run your node.js code. There are others ways to do such a job with child_process.
05_heavy_fork.js heavy_jobs.js
That's It!
Thank You!

More Related Content

What's hot

JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
Designveloper
 
Java DataBase Connectivity API (JDBC API)
Java DataBase Connectivity API (JDBC API)Java DataBase Connectivity API (JDBC API)
Java DataBase Connectivity API (JDBC API)
Luzan Baral
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patterns
José Paumard
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
Derek Willian Stavis
 
Nodejs presentation
Nodejs presentationNodejs presentation
Nodejs presentation
Arvind Devaraj
 
JS Event Loop
JS Event LoopJS Event Loop
JS Event Loop
Saai Vignesh P
 
emscriptenでC/C++プログラムをwebブラウザから使うまでの難所攻略
emscriptenでC/C++プログラムをwebブラウザから使うまでの難所攻略emscriptenでC/C++プログラムをwebブラウザから使うまでの難所攻略
emscriptenでC/C++プログラムをwebブラウザから使うまでの難所攻略
祐司 伊藤
 
Android Programming Seminar
Android Programming SeminarAndroid Programming Seminar
Android Programming Seminar
Nhat Nguyen
 
Java Programming
Java ProgrammingJava Programming
Java Programming
Elizabeth alexander
 
Core java
Core javaCore java
Core java
Shivaraj R
 
Network programming in Java
Network programming in JavaNetwork programming in Java
Network programming in Java
Tushar B Kute
 
Node js introduction
Node js introductionNode js introduction
Node js introduction
Joseph de Castelnau
 
Java Basics
Java BasicsJava Basics
Java Basics
Sunil OS
 
Golang workshop
Golang workshopGolang workshop
Golang workshop
Victor S. Recio
 
Introduction to Node js
Introduction to Node jsIntroduction to Node js
Introduction to Node js
Akshay Mathur
 
React js
React jsReact js
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test framework
Abner Chih Yi Huang
 
Modules in AngularJs
Modules in AngularJsModules in AngularJs
Modules in AngularJs
K Arunkumar
 
Android studio installation
Android studio installationAndroid studio installation
Android studio installation
Faysal Hossain Shezan
 
Completable future
Completable futureCompletable future
Completable future
Srinivasan Raghvan
 

What's hot (20)

JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Java DataBase Connectivity API (JDBC API)
Java DataBase Connectivity API (JDBC API)Java DataBase Connectivity API (JDBC API)
Java DataBase Connectivity API (JDBC API)
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patterns
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Nodejs presentation
Nodejs presentationNodejs presentation
Nodejs presentation
 
JS Event Loop
JS Event LoopJS Event Loop
JS Event Loop
 
emscriptenでC/C++プログラムをwebブラウザから使うまでの難所攻略
emscriptenでC/C++プログラムをwebブラウザから使うまでの難所攻略emscriptenでC/C++プログラムをwebブラウザから使うまでの難所攻略
emscriptenでC/C++プログラムをwebブラウザから使うまでの難所攻略
 
Android Programming Seminar
Android Programming SeminarAndroid Programming Seminar
Android Programming Seminar
 
Java Programming
Java ProgrammingJava Programming
Java Programming
 
Core java
Core javaCore java
Core java
 
Network programming in Java
Network programming in JavaNetwork programming in Java
Network programming in Java
 
Node js introduction
Node js introductionNode js introduction
Node js introduction
 
Java Basics
Java BasicsJava Basics
Java Basics
 
Golang workshop
Golang workshopGolang workshop
Golang workshop
 
Introduction to Node js
Introduction to Node jsIntroduction to Node js
Introduction to Node js
 
React js
React jsReact js
React js
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test framework
 
Modules in AngularJs
Modules in AngularJsModules in AngularJs
Modules in AngularJs
 
Android studio installation
Android studio installationAndroid studio installation
Android studio installation
 
Completable future
Completable futureCompletable future
Completable future
 

Viewers also liked

Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
Simen Li
 
專題製作發想與報告撰寫技巧
專題製作發想與報告撰寫技巧專題製作發想與報告撰寫技巧
專題製作發想與報告撰寫技巧
Simen Li
 
Agilent ADS 模擬手冊 [實習2] 放大器設計
Agilent ADS 模擬手冊 [實習2]  放大器設計Agilent ADS 模擬手冊 [實習2]  放大器設計
Agilent ADS 模擬手冊 [實習2] 放大器設計
Simen Li
 
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
Simen Li
 
全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版
Simen Li
 
Phase-locked Loops - Theory and Design
Phase-locked Loops - Theory and DesignPhase-locked Loops - Theory and Design
Phase-locked Loops - Theory and Design
Simen Li
 
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
Simen Li
 
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
Simen Li
 
電路學 - [第三章] 網路定理
電路學 - [第三章] 網路定理電路學 - [第三章] 網路定理
電路學 - [第三章] 網路定理
Simen Li
 
Multiband Transceivers - [Chapter 7] Spec. Table
Multiband Transceivers - [Chapter 7]  Spec. TableMultiband Transceivers - [Chapter 7]  Spec. Table
Multiband Transceivers - [Chapter 7] Spec. Table
Simen Li
 
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band TransceiversMultiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
Simen Li
 
Multiband Transceivers - [Chapter 7] Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
Multiband Transceivers - [Chapter 7]  Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...Multiband Transceivers - [Chapter 7]  Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
Multiband Transceivers - [Chapter 7] Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
Simen Li
 
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless RadiosMultiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
Simen Li
 
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
Simen Li
 

Viewers also liked (14)

Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
 
專題製作發想與報告撰寫技巧
專題製作發想與報告撰寫技巧專題製作發想與報告撰寫技巧
專題製作發想與報告撰寫技巧
 
Agilent ADS 模擬手冊 [實習2] 放大器設計
Agilent ADS 模擬手冊 [實習2]  放大器設計Agilent ADS 模擬手冊 [實習2]  放大器設計
Agilent ADS 模擬手冊 [實習2] 放大器設計
 
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
 
全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版
 
Phase-locked Loops - Theory and Design
Phase-locked Loops - Theory and DesignPhase-locked Loops - Theory and Design
Phase-locked Loops - Theory and Design
 
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
 
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
 
電路學 - [第三章] 網路定理
電路學 - [第三章] 網路定理電路學 - [第三章] 網路定理
電路學 - [第三章] 網路定理
 
Multiband Transceivers - [Chapter 7] Spec. Table
Multiband Transceivers - [Chapter 7]  Spec. TableMultiband Transceivers - [Chapter 7]  Spec. Table
Multiband Transceivers - [Chapter 7] Spec. Table
 
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band TransceiversMultiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
 
Multiband Transceivers - [Chapter 7] Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
Multiband Transceivers - [Chapter 7]  Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...Multiband Transceivers - [Chapter 7]  Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
Multiband Transceivers - [Chapter 7] Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
 
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless RadiosMultiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
 
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
 

Similar to Node.js Event Loop & EventEmitter

How NOT to write in Node.js
How NOT to write in Node.jsHow NOT to write in Node.js
How NOT to write in Node.js
Piotr Pelczar
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
Oleg Podsechin
 
Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)
William Farrell
 
Node js lecture
Node js lectureNode js lecture
Node js lecture
Darryl Sherman
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
Haci Murat Yaman
 
Alexander Reelsen - Seccomp for Developers
Alexander Reelsen - Seccomp for DevelopersAlexander Reelsen - Seccomp for Developers
Alexander Reelsen - Seccomp for Developers
DevDay Dresden
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
soft-shake.ch
 
Tips on how to improve the performance of your custom modules for high volume...
Tips on how to improve the performance of your custom modules for high volume...Tips on how to improve the performance of your custom modules for high volume...
Tips on how to improve the performance of your custom modules for high volume...Odoo
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: Serversideness
WebExpo
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
Visual Engineering
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
Piotr Pelczar
 
Jaap : node, npm & grunt
Jaap : node, npm & gruntJaap : node, npm & grunt
Jaap : node, npm & grunt
Bertrand Chevrier
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.
Mike Brevoort
 
To Err Is Human
To Err Is HumanTo Err Is Human
To Err Is Human
Alex Liu
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
Pavlo Baron
 
The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012Martin Schuhfuß
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
PROIDEA
 
Java util concurrent
Java util concurrentJava util concurrent
Java util concurrent
Roger Xia
 

Similar to Node.js Event Loop & EventEmitter (20)

How NOT to write in Node.js
How NOT to write in Node.jsHow NOT to write in Node.js
How NOT to write in Node.js
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)
 
Node js lecture
Node js lectureNode js lecture
Node js lecture
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
 
Alexander Reelsen - Seccomp for Developers
Alexander Reelsen - Seccomp for DevelopersAlexander Reelsen - Seccomp for Developers
Alexander Reelsen - Seccomp for Developers
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
 
Tips on how to improve the performance of your custom modules for high volume...
Tips on how to improve the performance of your custom modules for high volume...Tips on how to improve the performance of your custom modules for high volume...
Tips on how to improve the performance of your custom modules for high volume...
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: Serversideness
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
Jaap : node, npm & grunt
Jaap : node, npm & gruntJaap : node, npm & grunt
Jaap : node, npm & grunt
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.
 
To Err Is Human
To Err Is HumanTo Err Is Human
To Err Is Human
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
 
Java util concurrent
Java util concurrentJava util concurrent
Java util concurrent
 

More from Simen Li

2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
Simen Li
 
ADF4113 Frequency Synthesizer 驅動程式實作
ADF4113 Frequency Synthesizer 驅動程式實作ADF4113 Frequency Synthesizer 驅動程式實作
ADF4113 Frequency Synthesizer 驅動程式實作
Simen Li
 
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
Simen Li
 
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
Simen Li
 
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
Simen Li
 
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
Simen Li
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
Simen Li
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
Simen Li
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
Simen Li
 
深入淺出C語言
深入淺出C語言深入淺出C語言
深入淺出C語言
Simen Li
 
[嵌入式系統] 嵌入式系統進階
[嵌入式系統] 嵌入式系統進階[嵌入式系統] 嵌入式系統進階
[嵌入式系統] 嵌入式系統進階
Simen Li
 
Multiband Transceivers - [Chapter 5] Software-Defined Radios
Multiband Transceivers - [Chapter 5]  Software-Defined RadiosMultiband Transceivers - [Chapter 5]  Software-Defined Radios
Multiband Transceivers - [Chapter 5] Software-Defined Radios
Simen Li
 
Multiband Transceivers - [Chapter 3] Basic Concept of Comm. Systems
Multiband Transceivers - [Chapter 3]  Basic Concept of Comm. SystemsMultiband Transceivers - [Chapter 3]  Basic Concept of Comm. Systems
Multiband Transceivers - [Chapter 3] Basic Concept of Comm. Systems
Simen Li
 
Multiband Transceivers - [Chapter 2] Noises and Linearities
Multiband Transceivers - [Chapter 2]  Noises and LinearitiesMultiband Transceivers - [Chapter 2]  Noises and Linearities
Multiband Transceivers - [Chapter 2] Noises and Linearities
Simen Li
 
Multiband Transceivers - [Chapter 1]
Multiband Transceivers - [Chapter 1] Multiband Transceivers - [Chapter 1]
Multiband Transceivers - [Chapter 1]
Simen Li
 
RF Module Design - [Chapter 8] Phase-Locked Loops
RF Module Design - [Chapter 8] Phase-Locked LoopsRF Module Design - [Chapter 8] Phase-Locked Loops
RF Module Design - [Chapter 8] Phase-Locked Loops
Simen Li
 
RF Module Design - [Chapter 7] Voltage-Controlled Oscillator
RF Module Design - [Chapter 7] Voltage-Controlled OscillatorRF Module Design - [Chapter 7] Voltage-Controlled Oscillator
RF Module Design - [Chapter 7] Voltage-Controlled Oscillator
Simen Li
 

More from Simen Li (17)

2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
 
ADF4113 Frequency Synthesizer 驅動程式實作
ADF4113 Frequency Synthesizer 驅動程式實作ADF4113 Frequency Synthesizer 驅動程式實作
ADF4113 Frequency Synthesizer 驅動程式實作
 
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
 
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
 
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
 
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
 
深入淺出C語言
深入淺出C語言深入淺出C語言
深入淺出C語言
 
[嵌入式系統] 嵌入式系統進階
[嵌入式系統] 嵌入式系統進階[嵌入式系統] 嵌入式系統進階
[嵌入式系統] 嵌入式系統進階
 
Multiband Transceivers - [Chapter 5] Software-Defined Radios
Multiband Transceivers - [Chapter 5]  Software-Defined RadiosMultiband Transceivers - [Chapter 5]  Software-Defined Radios
Multiband Transceivers - [Chapter 5] Software-Defined Radios
 
Multiband Transceivers - [Chapter 3] Basic Concept of Comm. Systems
Multiband Transceivers - [Chapter 3]  Basic Concept of Comm. SystemsMultiband Transceivers - [Chapter 3]  Basic Concept of Comm. Systems
Multiband Transceivers - [Chapter 3] Basic Concept of Comm. Systems
 
Multiband Transceivers - [Chapter 2] Noises and Linearities
Multiband Transceivers - [Chapter 2]  Noises and LinearitiesMultiband Transceivers - [Chapter 2]  Noises and Linearities
Multiband Transceivers - [Chapter 2] Noises and Linearities
 
Multiband Transceivers - [Chapter 1]
Multiband Transceivers - [Chapter 1] Multiband Transceivers - [Chapter 1]
Multiband Transceivers - [Chapter 1]
 
RF Module Design - [Chapter 8] Phase-Locked Loops
RF Module Design - [Chapter 8] Phase-Locked LoopsRF Module Design - [Chapter 8] Phase-Locked Loops
RF Module Design - [Chapter 8] Phase-Locked Loops
 
RF Module Design - [Chapter 7] Voltage-Controlled Oscillator
RF Module Design - [Chapter 7] Voltage-Controlled OscillatorRF Module Design - [Chapter 7] Voltage-Controlled Oscillator
RF Module Design - [Chapter 7] Voltage-Controlled Oscillator
 

Recently uploaded

Software Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdfSoftware Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdf
MayankTawar1
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
vrstrong314
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Anthony Dahanne
 
Strategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptxStrategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptx
varshanayak241
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Natan Silnitsky
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Globus
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
WSO2
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
IES VE
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
 

Recently uploaded (20)

Software Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdfSoftware Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdf
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Strategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptxStrategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptx
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 

Node.js Event Loop & EventEmitter

  • 1. Event Loop & EventEmitter simen simenkid@gmail.com github.com/simenkid
  • 2. Materials • Demo Code ▫ https://github.com/simenkid/talks • Read More… ▫ https://simeneer.blogspot.tw/2016/09/nodejs-eventemitter.html
  • 3. Is Node.js Single Threaded? • Let’s run a simple http server var http = require('http'); var server = http.createServer(function (req, res) { // Request Handler }); server.listen(3000); “… Actually only your ‘userland’ code runs in one thread. … Node.js in fact spins up a number of threads.” - D. Khan, “How to track down CPU issues in Node.js” 01_server.js
  • 4. Concurrency “Concurrency is a way to structure a thing so that you can, maybe, use parallelism to do a better job. But parallelism is not the goal of concurrency; concurrency's goal is a good structure.” - R. Pike, Golang co-inventor TCP Server TCP Server Tasks spread over threads Tasks spread over time Requests Requests t t
  • 5. Blocking and Non-Blocking I/O • Simplified concepts of ▫ Blocking I/O ▫ Non-blocking I/O • I/O multiplexing ▫ Reactor ▫ select() or poll() ▫ Event notification, synchronous event demux
  • 6. Reactor Pattern Event Queue Event Demux (i.e., select() CallbackI/O Request register() Callback Execution Reactor
  • 7. Non-Blocking I/O Engine • libuv ▫ Node.js, Luvit, … ▫ multi-platform support library with a focus on asynchronous I/O http://docs.libuv.org/ Linux OSX, BSDs SunOS Windows
  • 8. Phases In the Loop ┌───────────────────────┐ ┌─>│ timers │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ I/O callbacks │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ idle, prepare │ │ └──────────┬────────────┘ ┌───────────────┐ │ ┌──────────┴────────────┐ │ incoming: │ │ │ poll │<─────┤ connections, │ │ └──────────┬────────────┘ │ data, etc. │ │ ┌──────────┴────────────┐ └───────────────┘ │ │ check │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ └──┤ close callbacks │ └───────────────────────┘ uv__run_timers() uv__run_pending() uv__run_idle() uv__run_prepare() uv__io_poll() uv__run_check() uv__run_closing_handles()
  • 9. libuv core.c int uv_run(uv_loop_t* loop, uv_run_mode mode) { // ... r = uv__loop_alive(loop); // ... while (r != 0 && loop->stop_flag == 0) { uv__update_time(loop); uv__run_timers(loop); ran_pending = uv__run_pending(loop); uv__run_idle(loop); uv__run_prepare(loop); timeout = 0; if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) timeout = uv_backend_timeout(loop); uv__io_poll(loop, timeout); uv__run_check(loop); uv__run_closing_handles(loop); if (mode == UV_RUN_ONCE) { uv__update_time(loop); uv__run_timers(loop); } r = uv__loop_alive(loop); // ... } https://github.com/libuv/libuv/blob/v1.x/src/unix/core.c#L332-L372 core.c
  • 10. Event Loop in Node.js (I) // Entry point for new node instances, ... static void StartNodeInstance(void* arg) { // ... { SealHandleScope seal(isolate); bool more; do { v8::platform::PumpMessageLoop(default_platform, isolate); more = uv_run(env->event_loop(), UV_RUN_ONCE); if (more == false) { v8::platform::PumpMessageLoop(default_platform, isolate); EmitBeforeExit(env); // Emit `beforeExit` if the loop became alive either after emitting // event, or after running some callbacks. more = uv_loop_alive(env->event_loop()); if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0) more = true; } } while (more == true); } // ... } node.cc
  • 11. Event Loop in Node.js (II) Environment* CreateEnvironment( Isolate* isolate, uv_loop_t* loop, // ... const char* const* exec_argv) { // ... uv_check_init(env->event_loop(), env->immediate_check_handle()); uv_unref( reinterpret_cast<uv_handle_t*>(env->immediate_check_handle())); uv_idle_init(env->event_loop(), env->immediate_idle_handle()); uv_prepare_init(env->event_loop(), env->idle_prepare_handle()); uv_check_init(env->event_loop(), env->idle_check_handle()); uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_prepare_handle())); uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_check_handle())); // Register handle cleanups env->RegisterHandleCleanup( reinterpret_cast<uv_handle_t*>(env->immediate_check_handle()), HandleCleanup, nullptr); // ... return env; } node.cc Each node instance has its own event loop.
  • 12. Put Tasks/Callbacks To Event Loop • Non-blocking I/O APIs ▫ fs.readFile(path, cb) • Timer Phase ▫ setTimeout(cb, time) ▫ setInterval(cb, time) • Check Phase ▫ setImmediate(cb) • At Each Phase End ▫ process.nextTick(cb) ▫ Microtasks (Promise) ┌───────────────────────┐ ┌─>│ timers │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ I/O callbacks │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ idle, prepare │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ poll │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ check │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ └──┤ close callbacks │ └───────────────────────┘ process.nextTick() Microtasks [ ] “Each phase has a FIFO queue of callbacks to execute.”
  • 13. How Long a Tick Is? “This is a tick: the synchronous invocation of zero or more callback functions associated with any external events. Once the queue is emptied out and the last function returns, the tick is over.” - josh3736, “What exactly is a Node.js event loop tick?” Answered@stackoverflow ┌───────────────────────┐ ┌─>│ timers │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ I/O callbacks │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ idle, prepare │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ poll │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ check │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ └──┤ close callbacks │ └───────────────────────┘ [ ] [ ] [ ] [ ] [ ] [ ]
  • 14. I/O Starvation function crazy() { console.log('Are you crazy?'); process.nextTick(function () { crazy(); }); } crazy(); [ ] [ ] [ ] crazy() nextTickQueue “ … any time you call process.nextTick() in a given phase, all callbacks passed to process.nextTick() will be resolved before the event loop continues. … "starve" your I/O by making recursive process.nextTick() calls, …”
  • 16. EventEmitter function EventEmitter() { EventEmitter.init.call(this); } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; // ... EventEmitter.init = function() { // ... if (!this._events || this._events === Object.getPrototypeOf(this)._events) { this._events = {}; this._eventsCount = 0; } this._maxListeners = this._maxListeners || undefined; }; The base class accommodates Observer Pattern in Node.js (Publish/Subscribe, Mediator Patterns) events.js
  • 17. APIs EventEmitter.prototype.setMaxListeners EventEmitter.prototype.getMaxListeners EventEmitter.prototype.emit (publish) EventEmitter.prototype.addListener (subscribe) EventEmitter.prototype.on = EventEmitter.prototype.addListener EventEmitter.prototype.once EventEmitter.prototype.removeListener EventEmitter.prototype.removeAllListeners EventEmitter.prototype.listeners EventEmitter.prototype.listenerCount events.js
  • 18. .on( ) EventEmitter.prototype.addListener = function addListener(type, listener) { var m; var events; var existing; if (typeof listener !== 'function') throw new TypeError('listener must be a function'); events = this._events; // ... if (!existing) { // Optimize the case of one listener. // Don't need the extra array object. existing = events[type] = listener; ++this._eventsCount; } else { if (typeof existing === 'function') { // Adding the second element, need to change to array. existing = events[type] = [existing, listener]; } else { // If we've already got an array, just append. existing.push(listener); } // ... } return this; }; event_name1: [ ] event_name3: [ ] event_name2: events.js
  • 19. .emit( ) EventEmitter.prototype.emit = function emit(type) { // ... events = this._events; // ... handler = events[type]; if (!handler) return false; // ... switch (len) { // fast cases case 1: emitNone(handler, isFn, this); break; case 2: emitOne(handler, isFn, this, arguments[1]); break; // ... // slower default: args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; emitMany(handler, isFn, this, args); } // ... return true; }; function emitMany(handler, isFn, self, args) { if (isFn) handler.apply(self, args); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].apply(self, args); } } event_name1: [ ] event_name3: [ ] event_name2: events.js
  • 21. Who Prints First? console.log('<0> schedule with setTimeout in 1-sec'); setTimeout(function () { console.log('[0] setTimeout in 1-sec boom!'); }, 1000); console.log('<1> schedule with setTimeout in 0-sec'); setTimeout(function () { console.log('[1] setTimeout in 0-sec boom!'); }, 0); console.log('<2> schedule with setImmediate'); setImmediate(function () { console.log('[2] setImmediate boom!'); }); console.log('<3> A immediately resolved promise'); aPromiseCall().then(function () { console.log('[3] promise resolve boom!'); }); console.log('<4> schedule with process.nextTick'); process.nextTick(function () { console.log('[4] process.nextTick boom!'); }); function aPromiseCall () { return new Promise(function(resolve, reject) { return resolve(); }); } What if these things are arranged in an I/O callback? 02_prints.js
  • 22. EventEmitter - Dead Loop var EventEmitter = require('events'); var crazy = new EventEmitter(); crazy.on('event1', function () { console.log('event1 fired!'); crazy.emit('event2'); }); crazy.on('event2', function () { console.log('event2 fired!'); crazy.emit('event3'); }); crazy.on('event3', function () { console.log('event3 fired!'); crazy.emit('event1'); }); crazy.emit('event1'); event1 event2event3 Synchronous Execution Loop What if scheduled with… • process.nextTick() • setImmediate() 03_deadloop.js
  • 23. Long-Running Tasks? • How to deal with my long-running tasks? ▫ Cut it down or use a worker • A ridiculous heavy task function doHeavy () { // Counts how many 1s occurred var count = 0; for (var i = 0; i < 1e8; i++) { if (Math.round(Math.log( Math.sqrt(Math.abs(Math.round(Math.random() * 1000))) )) === 1) count++; } return count; } setInterval(function () { console.log('I am not blocked'); }, 1000); console.log(doHeavy()); // Takes around 10 seconds on my machine 04_heavy.js
  • 24. Cut It Down (I) function doNotSoHeavy (times) { var count = 0; for (var i = 0; i < times; i++) { if (Math.round(Math.log( Math.sqrt(Math.abs(Math.round(Math.random() * 1000))) )) === 1) count++; } return count; } function doHeavy() { var total = 1e8, cuts = 100, counts = 0; for (var i = 0; i < cuts; i++) { counts = counts + doNotSoHeavy(total/cuts); } return counts; } setInterval(function () { console.log('I am not blocked'); }, 1000); console.log(doHeavy()); // Takes around 10 seconds on my machine Synchronous. Blocks? 04_heavy_cut_sync.js
  • 25. Cut It Down (II) function doHeavy(callback) { var total = 1e8, cuts = 100, counts = 0, remains = cuts; for (var i = 0; i < cuts; i++) { setImmediate(function () { counts = counts + doNotSoHeavy(total/cuts); remains--; if (!remains) { process.nextTick(function () { callback(counts); }); } }); } } doHeavy(function (counts) { console.log(counts); }); Need a callback to get the asynchronous result Asynchronous. Blocks? 04_heavy_cut_async1.js
  • 26. Cut It Down (III) function doHeavy(callback) { var total = 1e8, cuts = 100, counts = 0, remains = cuts; function doPerLoopIter() { setImmediate(function () { counts = counts + doNotSoHeavy(total/cuts); remains--; if (!remains) { process.nextTick(function () { callback(counts); }); } else { doPerLoopIter(); } }); } doPerLoopIter(); } doHeavy(function (counts) { console.log(counts); }); Asynchronous. Blocks? 04_heavy_cut_async2.js
  • 27. Cut It Down (IV) var heavyJobs = { counts: 0, queue: [], _callback: null, add: function (task) { this.queue.push(task); }, next: function (callback) { var self = this, task = this.queue.shift(); if (!task) return; setImmediate(function () { self.counts = self.counts + task(); if (self.queue.length === 0) self._callback(self.counts); else self.next(); }); }, do: function (callback) { this._callback = callback; this.next(); } }; var total = 1e8, cuts = 100; for (var i = 0; i < cuts; i++) { heavyJobs.add(function () { return doNotSoHeavy(total/cuts); }); } setInterval(function () { console.log('I am not blocked'); }, 1000); heavyJobs.do(function (counts) { console.log(counts); }); There are many ways to make your heavy jobs happy… 04_heavy_queue.js This example is for demonstrating the idea. Not very thoughtful.
  • 28. Run With Another Process var fork = require('child_process').fork; function doHeavyWithWorker(callback) { var worker = fork('./heavy_jobs.js'); worker.once('message', function (counts) { callback(counts); }); } setInterval(function () { console.log('I am not blocked'); }, 1000); doHeavyWithWorker(function (result) { console.log(result.counts); }); // heavy_jobs.js function doHeavy () { // Counts how many 1s occurred var count = 0; for (var i = 0; i < 1e8; i++) { if (Math.round(Math.log( Math.sqrt(Math.abs( Math.round(Math.random() * 1000)) ) )) === 1) count++; } return count; } var counts = doHeavy(); process.send({ counts: counts }); fork() establishes the IPC channel between parent and child for your convenience to run your node.js code. There are others ways to do such a job with child_process. 05_heavy_fork.js heavy_jobs.js