Something you should know about Event Loop!
Concept
- all JavaScript, V8, and the event loop run in one thread, called the main thread
- Node.js has two types of threads:
one event loop
andworker threads
- Libuv creates a pool with 4 threads (default) that is only used if no asynchronous API is available
- event loop is a set of phases with dedicated data structures for each phase
Micro-Task
- nextTick, promise are not part of Libuv, and are represented as an event loop on their own
- micro-task (nextTick, promise) uses the concept of a job queue
- micro-tasks’ callback will be executed immediately after the current phase of the event loop
Libuv’s Event Loop Phase
- data structure: timer (minHeap), immediate (queue)
Examples
In this case, setTimeout and setImmediate will be random order
console.log('start')
setTimeout(() => {
console.log('setTimeout')
}, 0)
setImmediate(() => {
console.log('setImmediate')
})
console.log('end')
// start
// end
// setImmediate (random order)
// setTimeout (random order)
In this case, because after the IO phase, the next phase is setImmediate
. So, setImmediate must before setTimeout
import { readFile } from 'fs'
console.log('start')
readFile('src/test.txt', (err, data) => {
setTimeout(() => {
console.log('setTimeout')
}, 0)
setImmediate(() => {
console.log('setImmediate')
})
if (!err) {
console.log(data.toString())
}
})
console.log('end')
// start
// end
// data
// setImmediate
// setTimeout
Libuv
Libuv will delegate the work to the
operating system kernel
whenever possibleThe only performance limitation is the network
- TCP/UDP servers and clients (network request)
- Pipes
- dns.resolve - Child processes
use libuv’s thread pool
- fs module (async function)
- dns.lookup
- Pipes (edge cases)
Thread Pool
- os concept: os has
scheduler
whose job is to allow certain processes to run on this 4-core system
Libuv’s thread pools (default = 4)
- tasks enqueue
- worker handles
- os scheduler handles
- core do something (parallel)