SlideShare a Scribd company logo
1 of 30
Download to read offline
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

Applications secure by default
Applications secure by defaultApplications secure by default
Applications secure by defaultSecuRing
 
Spring security oauth2
Spring security oauth2Spring security oauth2
Spring security oauth2axykim00
 
Node JS reverse shell
Node JS reverse shellNode JS reverse shell
Node JS reverse shellMadhu Akula
 
Introduction to Kotlin coroutines
Introduction to Kotlin coroutinesIntroduction to Kotlin coroutines
Introduction to Kotlin coroutinesRoman Elizarov
 
Original slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkOriginal slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkAarti Parikh
 
Utilizing kotlin flows in an android application
Utilizing kotlin flows in an android applicationUtilizing kotlin flows in an android application
Utilizing kotlin flows in an android applicationSeven Peaks Speaks
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in KotlinAlexey Soshin
 
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用Shengyou Fan
 
[OPD 2019] Attacking JWT tokens
[OPD 2019] Attacking JWT tokens[OPD 2019] Attacking JWT tokens
[OPD 2019] Attacking JWT tokensOWASP
 
Kotlin Coroutines in Practice @ KotlinConf 2018
Kotlin Coroutines in Practice @ KotlinConf 2018Kotlin Coroutines in Practice @ KotlinConf 2018
Kotlin Coroutines in Practice @ KotlinConf 2018Roman Elizarov
 
Node js presentation
Node js presentationNode js presentation
Node js presentationmartincabrera
 
Multithreading in java
Multithreading in javaMultithreading in java
Multithreading in javajunnubabu
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesLauren Yew
 
Getting Started in Pentesting the Cloud: Azure
Getting Started in Pentesting the Cloud: AzureGetting Started in Pentesting the Cloud: Azure
Getting Started in Pentesting the Cloud: AzureBeau Bullock
 

What's hot (20)

Java constructors
Java constructorsJava constructors
Java constructors
 
Applications secure by default
Applications secure by defaultApplications secure by default
Applications secure by default
 
Spring security oauth2
Spring security oauth2Spring security oauth2
Spring security oauth2
 
Demystifying OAuth 2.0
Demystifying OAuth 2.0Demystifying OAuth 2.0
Demystifying OAuth 2.0
 
Node JS reverse shell
Node JS reverse shellNode JS reverse shell
Node JS reverse shell
 
Introduction to Kotlin coroutines
Introduction to Kotlin coroutinesIntroduction to Kotlin coroutines
Introduction to Kotlin coroutines
 
Original slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkOriginal slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talk
 
Utilizing kotlin flows in an android application
Utilizing kotlin flows in an android applicationUtilizing kotlin flows in an android application
Utilizing kotlin flows in an android application
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in Kotlin
 
Nikto
NiktoNikto
Nikto
 
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
 
[OPD 2019] Attacking JWT tokens
[OPD 2019] Attacking JWT tokens[OPD 2019] Attacking JWT tokens
[OPD 2019] Attacking JWT tokens
 
Kotlin Coroutines in Practice @ KotlinConf 2018
Kotlin Coroutines in Practice @ KotlinConf 2018Kotlin Coroutines in Practice @ KotlinConf 2018
Kotlin Coroutines in Practice @ KotlinConf 2018
 
Node js presentation
Node js presentationNode js presentation
Node js presentation
 
Socket.IO
Socket.IOSocket.IO
Socket.IO
 
Multithreading in java
Multithreading in javaMultithreading in java
Multithreading in java
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
 
Java ppt
Java pptJava ppt
Java ppt
 
Sqlmap
SqlmapSqlmap
Sqlmap
 
Getting Started in Pentesting the Cloud: Azure
Getting Started in Pentesting the Cloud: AzureGetting Started in Pentesting the Cloud: Azure
Getting Started in Pentesting the Cloud: Azure
 

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, 2013Simen 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 DesignSimen 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. TableSimen 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 TransceiversSimen 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 RadiosSimen 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.jsPiotr 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 wayOleg 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 System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The LandingHaci Murat Yaman
 
Alexander Reelsen - Seccomp for Developers
Alexander Reelsen - Seccomp for DevelopersAlexander Reelsen - Seccomp for Developers
Alexander Reelsen - Seccomp for DevelopersDevDay 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.jssoft-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: ServersidenessWebExpo
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptVisual Engineering
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsPiotr Pelczar
 
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 HumanAlex 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 concurrentRoger 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 FirmwareSimen Li
 
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack FirmwareSimen 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 RadiosSimen 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. SystemsSimen 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 LinearitiesSimen 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 LoopsSimen 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 OscillatorSimen 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

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 

Recently uploaded (20)

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 

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