MEAN Node.js Async Patterns and Performance 4 — Questions and Answers
Question 1: What does the `util.promisify()` function do in Node.js?
- Converts a callback-based function to return a Promise (Correct answer)
- Converts a Promise to use callbacks
- Wraps a sync function to run asynchronously
- Creates a new EventEmitter instance
Correct answer: Converts a callback-based function to return a Promise
`util.promisify()` takes a function following the Node.js error-first callback convention and returns a version that returns Promises.
Question 2: Which Node.js method limits the concurrency of multiple async operations?
- Promise.all()
- Promise.race()
- Promise.allSettled()
- There is no built-in method; use a semaphore pattern (Correct answer)
Correct answer: There is no built-in method; use a semaphore pattern
Node.js has no built-in concurrency limiter; developers implement semaphore/queue patterns or use libraries like `p-limit` to cap parallel operations.
Question 3: What is the output order of this code: `console.log('A'); setTimeout(() => console.log('B'), 0); Promise.resolve().then(() => console.log('C')); console.log('D');`
- A, B, C, D
- A, D, B, C
- A, D, C, B (Correct answer)
- A, C, D, B
Correct answer: A, D, C, B
Synchronous code (A, D) runs first, then microtasks like Promise callbacks (C), then macrotasks like setTimeout (B).
Question 4: What is `AsyncLocalStorage` used for in Node.js?
- Persisting data to the filesystem asynchronously
- Storing request-scoped context across async operations without passing it explicitly (Correct answer)
- Caching async function results in memory
- Managing async generator state
Correct answer: Storing request-scoped context across async operations without passing it explicitly
`AsyncLocalStorage` provides a way to store data that is accessible throughout the lifetime of a web request or any other asynchronous duration.
Question 5: What happens when an unhandled rejection occurs in a Promise in Node.js v15+?
- The process emits a warning but continues running
- The process exits with a non-zero exit code (Correct answer)
- The rejection is silently ignored
- The event loop pauses until the rejection is handled
Correct answer: The process exits with a non-zero exit code
Since Node.js v15, unhandled Promise rejections cause the process to terminate with exit code 1 by default.
Question 6: Which pattern best prevents 'callback hell' in Node.js code?
- Using synchronous versions of all I/O functions
- Flattening callbacks with named functions or using Promises/async-await (Correct answer)
- Increasing the Node.js thread pool size
- Using `process.nextTick()` for every callback
Correct answer: Flattening callbacks with named functions or using Promises/async-await
Named functions or Promise/async-await patterns flatten deeply nested callbacks into readable sequential-looking code.
Question 7: What does `Promise.allSettled()` return compared to `Promise.all()`?
- It returns only the resolved values, same as Promise.all()
- It resolves with an array of outcome objects for all promises, never rejecting itself (Correct answer)
- It rejects as soon as one promise rejects, same as Promise.all()
- It resolves only when all promises reject
Correct answer: It resolves with an array of outcome objects for all promises, never rejecting itself
`Promise.allSettled()` waits for all promises to complete and returns an array of `{status, value/reason}` objects regardless of individual outcomes.
What does the `util.promisify()` function do in Node.js?