JavaScript Async Programming 2 — Questions and Answers
Question 1: What does the `Promise.allSettled()` method return?
- A promise that rejects if any input promise rejects
- A promise that resolves with an array of outcome objects for all promises (Correct answer)
- A promise that resolves with the first settled value
- An array of boolean values indicating promise states
Correct answer: A promise that resolves with an array of outcome objects for all promises
`Promise.allSettled()` waits for all promises to settle (either fulfill or reject) and returns a promise that resolves with an array of objects, each describing the outcome with a `status` property of `'fulfilled'` or `'rejected'`.
`Promise.allSettled()` was introduced in ES2020 and is useful when you want to know the result of every promise regardless of whether some fail. Each result object has `status: 'fulfilled'` with a `value` property, or `status: 'rejected'` with a `reason` property. This contrasts with `Promise.all()` which short-circuits on the first rejection.
Question 2: Which keyword is used to pause execution inside an async function until a promise resolves?
- pause
- wait
- await (Correct answer)
- yield
Correct answer: await
The `await` keyword is used inside `async` functions to pause execution until the awaited promise resolves or rejects, making asynchronous code look and behave like synchronous code.
`await` causes the async function to pause and wait for the Promise to resolve. If the Promise rejects, the `await` expression throws the rejection value, which can be caught with try/catch. `yield` is used in generator functions, `pause` and `wait` are not JavaScript keywords.
Question 3: What is the output of: `console.log(1); setTimeout(() => console.log(2), 0); console.log(3);`?
- 1, 2, 3
- 2, 1, 3
- 1, 3, 2 (Correct answer)
- 3, 1, 2
Correct answer: 1, 3, 2
Synchronous code runs first: `1` and `3` are logged immediately. The `setTimeout` callback is placed in the macrotask queue and runs after the call stack is empty, so `2` is logged last.
JavaScript is single-threaded. `setTimeout` schedules the callback in the macrotask queue regardless of the delay value. The event loop only processes the queue after the current synchronous execution context (call stack) is empty. So the order is: synchronous `1`, synchronous `3`, then queued `2`.
Question 4: What does `Promise.race()` return?
- A promise that resolves after all promises resolve
- A promise that resolves or rejects with the value of the first settled promise (Correct answer)
- A promise that always resolves with the fastest fulfilled value
- An array of the first values from each promise
Correct answer: A promise that resolves or rejects with the value of the first settled promise
`Promise.race()` returns a promise that settles (resolves or rejects) as soon as the first input promise settles, adopting its value or reason.
`Promise.race()` is useful for implementing timeouts. If the first settled promise fulfills, the race fulfills; if it rejects, the race rejects. Other promises continue running but their results are ignored. Unlike `Promise.any()`, `Promise.race()` also resolves with the first rejection.
Question 5: How do you handle errors in async/await code?
- Using .catch() on the async function call only
- Using try/catch blocks inside the async function (Correct answer)
- Using the `onerror` event handler
- Errors cannot be handled in async/await
Correct answer: Using try/catch blocks inside the async function
You can wrap `await` expressions in `try/catch` blocks to handle rejected promises. You can also chain `.catch()` on the returned promise, but try/catch is the idiomatic approach inside async functions.
When an `await`ed promise rejects, it throws an error that can be caught by a surrounding `try/catch`. This is one of the major advantages of async/await — it allows you to use familiar error handling patterns rather than chaining `.catch()` handlers. Both approaches work, and you can combine them.
Question 6: What is a 'microtask' in JavaScript's event loop?
- A small setTimeout with 1ms delay
- A task queued by Promise callbacks, processed before the next macrotask (Correct answer)
- Any function shorter than 10 lines
- A Web Worker task
Correct answer: A task queued by Promise callbacks, processed before the next macrotask
Microtasks (such as Promise `.then()` callbacks) are queued in the microtask queue and are processed after the current synchronous code finishes but before the next macrotask (like `setTimeout` callbacks).
The event loop processes all microtasks in the queue before moving on to the next macrotask. This means `Promise.resolve().then(cb)` will always run before `setTimeout(cb, 0)`. Other sources of microtasks include `queueMicrotask()` and `MutationObserver` callbacks. Understanding this order is crucial for predicting async execution order.
What does the `Promise.allSettled()` method return?