Node.js is known for its efficient and scalable I/O model, which is based on a non-blocking, event-driven architecture. This means that I/O operations are handled asynchronously and do not block the execution of the main program. In contrast to traditional blocking I/O models, where the program waits for each I/O operation to complete before continuing to the next one, Node.js can execute multiple I/O operations simultaneously.
Here are some key points that explain how Node.js achieves non-blocking I/O:
fs
module provides non-blocking methods for reading and writing files. When these methods are called, Node.js immediately returns control to the program, allowing it to continue executing other code. Once the I/O operation completes, the callback function is called with the result.Blocking code example:
const getUserSync = (userId) => {
const users = {
1: { name: 'John', age: 35 },
2: { name: 'Jane', age: 28 }
};
return users[userId];
}
const user = getUserSync(1);
console.log(user);
In this example, the getUserSync
function returns a user object from a hardcoded list of users. This function is blocking, because it executes synchronously and returns the result immediately.
Non-blocking code example:
const getUserAsync = (userId, callback) => {
const users = {
1: { name: 'John', age: 35 },
2: { name: 'Jane', age: 28 }
};
setTimeout(() => {
callback(users[userId]);
}, 1000);
}
getUserAsync(1, (user) => {
console.log(user);
});
In this example, the getUserAsync
function returns a user object from a hardcoded list of users, but it executes asynchronously, using the setTimeout
function to delay the execution of the callback function by 1 second. The getUserAsync
function takes a callback function as its second argument, which is called with the user object once it has been retrieved.