-
What is the event loop in Node.js, and how does it work?
- Answer: The event loop is a core part of Node.js's runtime that handles asynchronous operations. Node.js is single-threaded, and the event loop allows non-blocking I/O operations by offloading tasks to the operating system whenever possible. It continuously checks for pending callbacks, I/O events, timers, and handles them in a loop, which makes Node.js highly efficient for I/O-bound tasks.
-
Explain the difference between
setImmediateandprocess.nextTickin Node.js.- Answer:
setImmediateschedules a callback to execute on the next iteration of the event loop, after I/O events.process.nextTickadds a callback to the next tick queue, which gets executed before the event loop continues.process.nextTickhas a higher priority thansetImmediate.
- Answer:
-
How does Node.js handle concurrency?
- Answer: Node.js handles concurrency using the event loop and a thread pool provided by the libuv library. While JavaScript runs on a single thread, I/O operations, file system tasks, and other long-running operations are offloaded to the thread pool. This allows Node.js to handle multiple operations concurrently without blocking the main thread.
-
What are streams in Node.js, and how do they work?
- Answer: Streams in Node.js are objects that let you read data from a source or write data to a destination in a continuous fashion. There are four types of streams: Readable, Writable, Duplex, and Transform. Streams are efficient because they handle data chunk by chunk, which is ideal for working with large files.
-
What is a buffer in Node.js, and when would you use it?
- Answer: A buffer in Node.js is a temporary storage area for binary data. Buffers are used when dealing with raw binary data, such as reading files or handling streams of data over a network connection. Buffers are necessary because JavaScript strings are UTF-16 encoded and do not support binary data directly.
-
How do you manage uncaught exceptions in Node.js?
- Answer: Uncaught exceptions can be managed using the
process.on('uncaughtException', handler)event. However, relying on this should be a last resort, as it is better to handle errors appropriately in your code. For better control, usingdomainsortry-catchblocks for synchronous code andpromise.catchor error callbacks for asynchronous code is recommended.
- Answer: Uncaught exceptions can be managed using the
-
Explain the role of the
package.jsonfile in a Node.js project.- Answer: The
package.jsonfile is the heart of a Node.js project. It contains metadata about the project, such as the name, version, and dependencies. It also includes scripts, author details, and configuration options. Thepackage.jsonfile is essential for managing dependencies, scripts, and project information.
- Answer: The
-
What is the difference between
requireandimportin Node.js?- Answer:
requireis used in Node.js to load modules using CommonJS, whileimportis used for ES6 module syntax.requireis synchronous and can be used anywhere in the code, whileimportis asynchronous and must be at the top of the file. ES6 modules provide features like static analysis, tree shaking, and improved performance.
- Answer:
-
How does Node.js handle file system operations?
- Answer: Node.js provides the
fsmodule to handle file system operations. It offers both synchronous and asynchronous methods for reading, writing, updating, and deleting files. The asynchronous methods are non-blocking and are preferred in most cases to avoid blocking the event loop.
- Answer: Node.js provides the
-
What are worker threads in Node.js, and when would you use them?
- Answer: Worker threads allow you to run JavaScript code in parallel. They are useful for CPU-bound tasks that would otherwise block the event loop. Worker threads are not typically needed for I/O-bound tasks, as Node.js handles them efficiently with the event loop and libuv.
Asynchronous Programming
-
Explain the concept of callbacks in Node.js. What are callback hell and how can you avoid it?
- Answer: A callback is a function passed as an argument to another function, which is then invoked after an asynchronous operation completes. Callback hell refers to the situation where callbacks are nested within callbacks, making the code hard to read and maintain. It can be avoided using Promises, async/await, or modularizing the code.
-
What are Promises in Node.js, and how do they improve code readability?
- Answer: Promises represent the eventual completion (or failure) of an asynchronous operation and its resulting value. They improve code readability by flattening the nested callback structure into a more linear and manageable sequence of
.then()calls, and they can be further improved using async/await syntax.
- Answer: Promises represent the eventual completion (or failure) of an asynchronous operation and its resulting value. They improve code readability by flattening the nested callback structure into a more linear and manageable sequence of
-
How does async/await work in Node.js, and what are its benefits?
- Answer:
asyncandawaitare syntactic sugar on top of Promises, allowing asynchronous code to be written in a synchronous style. Anasyncfunction returns a Promise, andawaitpauses the execution until the Promise is resolved. This makes the code easier to read and maintain, reducing the chances of callback hell.
- Answer:
-
What is the purpose of the
util.promisifymethod in Node.js?- Answer:
util.promisifyconverts a callback-based function into a Promise-based function, making it easier to work with async/await. This is particularly useful for older Node.js APIs that do not return Promises. -
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);async function readFileAsync() {
const data = await readFile('example.txt', 'utf8');
console.log(data);
}
- Answer:
-
What are async iterators and generators in Node.js, and how do they differ from regular iterators?
Answer: Async iterators and generators allow you to iterate over data asynchronously. A regular iterator returns a value synchronously with each iteration, while an async iterator returns a Promise, allowing you to await the resolution of each value. Async generators are functions that can yield values asynchronously, pausing and resuming execution as needed.async function* asyncGenerator() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}(async () => {
for await (let value of asyncGenerator()) {
console.log(value);
}
})();
-
What is the difference between
Promise.allandPromise.race?
Answer:Promise.allwaits for all Promises to resolve (or any to reject) and returns an array of results.Promise.race, on the other hand, returns the result of the first Promise to settle (either resolve or reject).const p1 = new Promise((resolve) => setTimeout(resolve, 100, 'one'));
const p2 = new Promise((resolve) => setTimeout(resolve, 200, 'two'));Promise.all([p1, p2]).then((values) => {
console.log(values); // ['one', 'two']
});Promise.race([p1, p2]).then((value) => {
console.log(value); // 'one'
});
-
How do you handle errors in async/await?
Answer: Errors in async/await can be handled usingtry-catchblocks. You wrap theawaitexpression in atryblock, and handle any errors in thecatchblock.
async function fetchData() {
try {
const data = await getData();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
} -
What is an event emitter in Node.js?
- Answer: An event emitter is a pattern in Node.js that allows objects to emit events and handle those events through listeners. The
EventEmitterclass in theeventsmodule is used to create, fire, and listen to events. This pattern is useful for decoupling code, where different parts of the application can respond to events asynchronously.
- Answer: An event emitter is a pattern in Node.js that allows objects to emit events and handle those events through listeners. The
-
How does the
asyncmodule help in handling asynchronous operations in Node.js?- Answer: The
asyncmodule provides utility functions for working with asynchronous JavaScript. It offers a variety of methods to handle tasks such as parallel execution, series execution, and controlling the concurrency level, making it easier to manage complex asynchronous workflows.
- Answer: The
-
What are the common pitfalls of asynchronous programming in Node.js, and how can you avoid them?
- Answer: Common pitfalls include callback hell, unhandled Promise rejections, race conditions, and memory leaks due to improperly handled callbacks. These can be avoided by using Promises, async/await, proper error handling, avoiding shared mutable state, and using tools like Node.js’s built-in memory leak detectors.






