Event Loop Notes
oswaldo.herrera@WIZELINE.com
@wdonet
Is that simple ?
from node.university
heard of it as ... ?
Heap
Event Loop
Stack
Execution Context
Memory Allocation
Callback queue
onfocus callback()
onload callback()
onclick callback()
Web APIs
DOM
XMLHttpRequest
setTimeout
call1()
call3()
call2()
static uv_thread_t default_threads[4];
#define MAX_THREADPOOL_SIZE 128
More big pictures
More complex yet
phases
callbacks scheduled by
setTimeout() and setInterval()
IO related callbacks except those scheduled by timers and setImmediate()
used internally
setImmediate() callbacks
i.e. socket.on('close', ...)
retrieve new I/O events
or ticks
callback
resolve promise
next scheduled tick
LIBUV
Timers Phase
A timer specifies a threshold
TIME
now
100ms
The poll phase controls when timers are executed
(as early as possible after the threshold)
setTimeout(() => {}, 100);
Timers Phase
TIME
threshold
var fs = require('fs');
function someAsyncOperation (callback) {
// Assume this takes 95ms to complete
fs.readFile('/path/to/file', callback);
}
var timeoutScheduled = Date.now();
setTimeout(function () {
var delay = Date.now() - timeoutScheduled;
console.log(delay + "ms have passed since I was scheduled");
}, 100);
// do someAsyncOperation which takes 95 ms to complete
someAsyncOperation(function () {
var startCallback = Date.now();
// do something that will take 10ms...
while (Date.now() - startCallback < 10) {
; // do nothing
}
});
timeoutScheduled
100ms
setTimeout() callback
fs.readFile( f ) ends
95ms
10ms
f()
105ms
105ms have passed since I was scheduled
Timers Phase Demo
I/O callbacks Phase
executes callbacks for some
system operations
(network - disk files - database connections)
ECONNREFUSED
ETIMEDOUT
i.e. TCP sockets
Poll Phase
Jump to Check Phase
callback queue empty ?
Execute
do
WHILE
- callback exists, and
- OS hard limit not reached
YES
NO
NO
YES
Is there a script scheduled by setImmediate() ?
Execute
all timers who reached threshold
NO
YES
Check Phase
execute callbacks (almost) immediately
after the poll phase has completed
setImmediate( callback() )
If poll phase becomes idle, executes
at the check phase .
Close Callbacks Phase
executes callbacks for
"close" events
and for
cleaning things
websocket.close()
EventEmitter.on('close', () => {})
i.e.
socket.end()
Event Loop Phases
for setTimeout() & setInterval()
for IO related callbacks
for setImmediate() callbacks
for closing events
executes queued callback
( Again )
setTimeout()
setImmediate()
// timervsimmediate.js
setTimeout(function timeout () {
console.log('timeout');
},0);
setImmediate(function immediate () {
console.log('immediate');
});
setTimeout()
setImmediate()
// immediateOverTimer.js
var fs = require('fs')
fs.readFile(__filename, () => {
setTimeout(() => {
console.log('timeout')
}, 0)
setImmediate(() => {
console.log('immediate')
})
});
setImmediate() will always execute before any timer,
if it is scheduled within an I/O cycle
process.nextTick()
callback
resolve promise
next scheduled tick
nextTickQueue()
micro tasks
Callback queue
scheduled callback()
scheduled callback()
scheduled callback()
happens inside the same phase
process.nextTick()
// this has an asynchronous signature, but calls callback synchronously
function someAsyncApiCall (callback) { callback(); };
// the callback is called before `someAsyncApiCall` completes.
someAsyncApiCall(() => {
// since someAsyncApiCall has completed, bar hasn't been assigned any value
console.log('bar', bar); // undefined
});
var bar = 1;
function someAsyncApiCall (callback) {
process.nextTick(callback);
};
someAsyncApiCall(() => {
console.log('bar', bar); // 1
});
var bar = 1;
would work ?
and this ?
function apiCall (arg, callback) {
if (typeof arg !== 'string')
return process.nextTick(callback,
new TypeError('argument should be string'));
}
process.nextTick()
real life examples
const server = net.createServer(() => {}).listen(8080);
server.on('listening', () => {});
process.nextTick()
Executes at same phase
Main reasons:
- Cleaning : error handling, unnecessary resources cleaning or re-try request
- Run operations before loop continues
setImmediate()
Executes at next tick (phase)
Compatible with browser JS and + environments
Easier to reason about
Event Loop Notes
By Oswaldo Herrera
Event Loop Notes
Event Loop notes that worth to share
- 869