Backend
Node.js
V8, libuv, and File Operations

Understanding Node.js: V8, libuv, and File Operations

Overview

Node.js leverages the V8 engine and the libuv library to provide efficient handling of both synchronous and asynchronous operations. This document explains the fundamental concepts of V8, libuv, and their interactions with file operations, including real-world code examples that demonstrate correct and incorrect usage of synchronous and asynchronous functions.


Key Concepts

V8 Engine

  • Purpose: Executes JavaScript code.
  • Behavior: Runs JavaScript synchronously in a single thread, processing one line of code at a time.

libuv Library

  • Purpose: Handles asynchronous operations (I/O, file system, network, timers, etc.).
  • Behavior: Manages the event loop and offloads time-consuming operations to worker threads or system-level resources, ensuring non-blocking behavior.

Synchronous vs Asynchronous

Synchronous Code Example (sync.js)

console.log("Synchronous Code")
 
var a = 62656954;
var b = 6256546;
 
function multiply(a, b) {
    const result = a * b
    return result
}
var c = multiply(a, b);
console.log("Multiplication of a and b is " + c)
  • All operations execute one after the other.
  • Blocks the main thread until execution finishes.

Asynchronous File Operation (Correct vs Incorrect)

Incorrect Usage of fs.readFileSync

fs.readFileSync('./file.txt', 'utf-8', (err, data) => {
    console.log("File data fetched synchronously: ", data);
});
  • ❌ fs.readFileSync is synchronous and does not accept a callback.

Correct Usage

try {
    const dataSync = fs.readFileSync('./file.txt', 'utf-8');
    console.log("File data fetched synchronously: ", dataSync);
} catch (err) {
    console.error("Error reading file synchronously: ", err);
}
  • âś… Blocks the main thread and returns data directly.

Asynchronous JavaScript Example (asyn.js)

const fs = require("fs");
const https = require("https");
 
console.log("Asynchronous Javascript")
 
var a = 5;
var b = 10;
 
fs.readFileSync("./file.txt", "utf8");
console.log("This will execute only after reading the file")
 
https.get("https://dummyjson.com/products/1", (res) => {
    console.log("data fetch successfully")
})
 
setTimeout(() => {
    console.log("Execute it after 5 seconds")
}, 5000)
 
fs.readFile("./file.txt", "utf-8", (err, data) => {
    console.log("file data:" + data)
})
 
function multiply(x, y) {
    const result = x * y;
    return result
}
 
const c = multiply(a, b)
console.log("Multiplication ans is:" + c)
  • Demonstrates async file reading (fs.readFile), HTTP request (https.get), and timer (setTimeout).
  • None of these block the main thread.

Blocking Example (blocking.js)

const crypto = require("node:crypto")
 
console.log("Program started")
 
crypto.pbkdf2Sync("myownpassword", "salt", 5000000, 20, "sha512");
console.log("Fist synchronous key is generated ")
 
crypto.pbkdf2("myownpassword", "salt", 50000, 20, "sha512", (err, key) => {
    console.log("Below is the asynchronous key of your password")
    console.log(key)
})
 
function addition(x, y) {
    const result = x + y;
    return result;
}
 
var c = addition(5, 10);
console.log("Addition is: " + c)
  • pbkdf2Sync blocks the event loop.
  • pbkdf2 executes asynchronously using libuv.

Zero Delay Timer (setTimeoutZero.js)

console.log("SetTimeoutZero demonstration");
 
var a = 5;
var b = 10;
 
setTimeout(() => {
    console.log("SetTimeout function after 3 seconds")
}, 3000);
 
setTimeout(() => {
    console.log("Call me asap")
}, 0);
 
function multiply(x, y) {
    const result = x * y;
    return result
}
 
const c = multiply(a, b);
console.log("Multiplication answer is : " + c)
  • setTimeout(() => {}, 0) runs after the synchronous code.
  • Demonstrates how timers are queued and handled asynchronously.

Summary

Synchronous Code

  • Runs top to bottom and blocks main thread.
  • Good for quick, guaranteed sequential execution.
  • Examples: readFileSync, pbkdf2Sync

Asynchronous Code

  • Handled by libuv and the event loop.
  • Does not block other operations.
  • Examples: readFile, pbkdf2, setTimeout, https.get

Why It Matters

  • Efficient I/O handling.
  • Better scalability and performance under load.
  • Enables real-time features and non-blocking APIs.

Appendix

file.txt Content:

Hi I am a Node.js Developer

Core Libraries Used

  • fs: File System module for reading/writing files.
  • https: For HTTP requests.
  • crypto: For cryptographic operations.
  • setTimeout: For scheduling delayed execution.

Node.js is built for concurrency, and understanding the balance between blocking and non-blocking code is crucial for writing high-performance applications. With V8's speed and libuv's powerful async capabilities, Node.js shines in scenarios requiring I/O efficiency and real-time responsiveness.