---
title: "Async JavaScript: Promises, Async/Await, Event Loop"
description: "Master asynchronous JavaScript: callbacks, Promises, async/await, event loop, microtasks. Essential for modern backend and frontend development."
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/quizzes/post/async-javascript-promises-quiz
---

# Async JavaScript: Promises, Async/Await, Event Loop

Welcome to the Async JavaScript quiz! Test your knowledge of Promises, async/await, the event loop, and advanced concurrency patterns. Each question has a hint and detailed explanations for all options. Good luck!

## Questions

### 1. What is the JavaScript event loop?

- **The mechanism that monitors the call stack and moves tasks from the callback queue to the stack** ✅
  - Event loop: checks queue when stack empty. Processes one event at a time.
- A background process that parallelizes JavaScript execution across multiple CPU cores
  - JavaScript is single-threaded; the event loop manages concurrency, not true parallelism.
- A built-in garbage collection routine that clears unused variables from the heap during idle time
  - The event loop manages the execution of code, not memory management or garbage collection.
- A network synchronization tool used to coordinate data between the browser and the server
  - This describes network protocols or WebSockets rather than the internal JS execution model.

**Hint:** Think about asynchronous execution.

### 2. What is a callback function?

- **A function passed into another function as an argument to be executed at a later time** ✅
  - Callbacks: common in Node.js. Can lead to callback hell.
- A specialized function that automatically retries an operation if it fails to resolve
  - While callbacks can be used in retry logic, they are not retry mechanisms by definition.
- A reserved keyword used to return the result of an asynchronous operation to the global scope
  - Callback is a pattern, not a reserved JavaScript keyword or a scoped return mechanism.
- A native method used to trigger the immediate termination of a running asynchronous process
  - This describes an AbortSignal or process.exit(), not the definition of a callback.

**Hint:** Think about a function passed to another function.

### 3. What is callback hell?

- **A situation where deeply nested callbacks make code difficult to read and manage errors** ✅
  - Pyramid of doom: unreadable code. Solutions: Promises, async/await.
- An execution error occurring when a recursive function exceeds the maximum call stack size
  - This describes a stack overflow, not the readability/management issue of nested callbacks.
- A memory leak caused by retaining references to functions that are no longer being used
  - While nested functions can cause leaks, callback hell specifically refers to code structure.
- A race condition where multiple callbacks attempt to update the same global state simultaneously
  - Race conditions are concurrency bugs; callback hell is a code organization/maintainability issue.

**Hint:** Think about deeply nested callbacks.

### 4. What is a Promise?

- **An object representing the eventual completion or failure of an asynchronous operation** ✅
  - Promise: states (pending, fulfilled, rejected). Better error handling than callbacks.
- A synchronous wrapper that forces an asynchronous function to return an immediate value
  - Promises are inherently asynchronous and do not return immediate values from the future.
- A global event emitter used to broadcast state changes across different parts of an application
  - This describes the Observer pattern or EventEmitter, not the core definition of a Promise.
- A browser-only API designed to handle communication between different windows or tabs
  - Promises are a language feature available in both browser and server-side environments.

**Hint:** Think about representing a future value.

### 5. What does Promise.resolve() do?

- **Returns a Promise object that is resolved with a specified value or result** ✅
  - Promise.resolve(value): shorthand for `new Promise(r => r(value))`.
- Immediately triggers the .then() block of every pending Promise in the current queue
  - It only creates a new resolved Promise; it does not trigger other unrelated Promises.
- Converts a synchronous function into an asynchronous one without changing its return type
  - It wraps a value in a Promise, but does not transform the underlying function architecture.
- Clears all rejected Promises from the microtask queue to prevent application crashes
  - This is not a feature of the Promise API; errors must be handled via .catch() or try/catch.

**Hint:** Think about returning a resolved Promise.

### 6. What does Promise.reject() do?

- **Returns a Promise object that is rejected with a given reason or error message** ✅
  - Promise.reject(reason): for error cases. Caught by .catch().
- Terminates the execution of the current script to prevent further async operations
  - It merely returns a rejected Promise; it does not stop the entire script execution.
- Prevents a Promise from ever settling to ensure that its callbacks are never executed
  - Rejection is a form of settlement; it does not leave the Promise in a pending state.
- Automatically triggers a retry of the asynchronous operation using backoff logic
  - Retry logic must be implemented manually; Promise.reject() only signals a failure state.

**Hint:** Think about returning a rejected Promise.

### 7. What is an async function?

- **A function that always returns a Promise and allows the use of the await keyword** ✅
  - async function: syntax sugar for `.then()` chains. Cleaner code.
- A specialized function that runs on a separate thread to avoid blocking the UI
  - Async functions still run on the main thread; they use the event loop for non-blocking I/O.
- A function that executes immediately and pauses the event loop until it completes
  - This would be a blocking synchronous function, the opposite of the purpose of async/await.
- A reserved constructor used to create new asynchronous classes in modern JavaScript
  - Async is a modifier for functions, not a constructor for creating specific class types.

**Hint:** Think about syntactic sugar for Promises.

### 8. What is the purpose of the await keyword?

- **Pauses the execution of an async function until a Promise settles and returns its result** ✅
  - await: pauses function execution. Throws if Promise rejects.
- Speeds up the execution of multiple Promises by running them in parallel threads
  - Awaiting multiple items sequentially is actually slower than parallel execution patterns.
- Directly converts a Promise into a synchronous value available in the global scope
  - Await only works inside async functions and does not make values available globally.
- Forces the event loop to prioritize the current task over all other pending microtasks
  - Await does not change task priority; it merely yield control back to the loop while waiting.

**Hint:** Think about pausing execution.

### 9. How does Promise.all() behave?

- **Fulfills when all input Promises fulfill, but rejects immediately if any Promise rejects** ✅
  - Promise.all(): parallel execution. Fast but all-or-nothing semantics.
- Fulfills as soon as the first Promise resolves, regardless of the state of others
  - This describes Promise.any() or Promise.race(), depending on the specific success/failure rules.
- Executes a list of asynchronous functions one after another in a strict sequential order
  - Promise.all() initiates operations concurrently; it does not enforce sequential execution.
- Returns an array of results only after every Promise has either fulfilled or rejected
  - This describes Promise.allSettled(), which does not reject early on individual failures.

**Hint:** Think about waiting for multiple Promises.

### 10. What is the behavior of Promise.race()?

- **Returns a Promise that settles as soon as any of the input Promises fulfill or reject** ✅
  - Promise.race(): useful for timeouts, first-to-complete patterns.
- Waits for all Promises to complete and returns the one that took the least time
  - It does not wait for all; it settles as soon as the first one does.
- Rejects only if all of the provided Promises fail to resolve within a given timeout
  - It settles based on the very first completion, whether it is a success or a failure.
- Prioritizes the fastest network request while cancelling all other slower operations
  - It ignores other results, but it does not automatically cancel pending network requests.

**Hint:** Think about the first settled Promise.

### 11. What is the microtask queue?

- **A high-priority queue for Promises and MutationObservers processed before the next macrotask** ✅
  - Microtasks: processed between macrotasks. Promises faster than setTimeout.
- A low-priority queue used for UI rendering and handling user input events like clicks
  - UI rendering and input events are generally handled in the macrotask queue.
- A temporary storage area for variables that are passed between different Web Workers
  - Web Workers use message passing; microtasks are part of the main event loop architecture.
- A debugging tool used to track the memory allocation of small objects in the heap
  - The microtask queue is an execution mechanism, not a memory profiling or debugging tool.

**Hint:** Think about Promise callback timing.

### 12. How does setTimeout interact with the event loop?

- **It schedules a callback to be executed as a macrotask after the current stack and microtasks** ✅
  - setTimeout: runs after all microtasks. Promises run first.
- It pauses the event loop for a set duration to ensure no other code executes
  - SetTimeout is non-blocking; it allows the event loop to continue while the timer runs.
- It injects a function directly into the microtask queue for immediate execution
  - SetTimeout is a macrotask; Promises and process.nextTick are used for microtasks.
- It bypasses the event loop to execute code on a separate background system thread
  - Timer logic may be handled by the system, but the callback always returns to the main loop.

**Hint:** Think about macrotask timing.

### 13. What is error handling with async/await?

- **The use of try/catch blocks to capture and handle errors from awaited Promises** ✅
  - try/catch: cleaner than .catch(). Catches both sync and async errors.
- The mandatory use of the .onerror() property on all asynchronous function declarations
  - There is no native .onerror property for functions; standard error handling patterns are used.
- A global monitoring system that automatically suppresses all asynchronous rejections
  - Async rejections must be handled explicitly; they are not suppressed by the language.
- The practice of returning null instead of throwing an error when an operation fails
  - While possible, this is a design choice and not the standard way to handle async errors.

**Hint:** Think about try/catch.

### 14. What is the use case for Promise.allSettled()?

- **When you need to wait for all operations to complete regardless of their individual success or failure** ✅
  - Promise.allSettled(): all results, no early rejection. Robust error handling.
- When you want to stop the execution of a batch of Promises as soon as any one of them fails
  - This describes Promise.all(), which features early rejection on the first failure.
- When you need to find the fastest successful response from a group of mirrored API endpoints
  - This describes Promise.any(), which specifically looks for the first successful fulfillment.
- When you are working with legacy callback-based code that does not support modern error objects
  - AllSettled is a modern Promise feature and does not relate to legacy callback compatibility.

**Hint:** Think about all Promises without early rejection.

### 15. What is the behavior of Promise.any()?

- **It returns the first Promise that fulfills, and only rejects if every input Promise rejects** ✅
  - Promise.any(): opposite of Promise.race() in rejection behavior. ES2021.
- It returns the first Promise that settles, whether it was a success or a rejection
  - This describes Promise.race(), which does not ignore rejections while waiting for a success.
- It combines the results of all fulfilled Promises into a single aggregate success object
  - It only returns the first single fulfillment, not an aggregate of all successes.
- It cancels all pending Promises once any of the input Promises has successfully resolved
  - It ignores the other Promises, but it does not have the authority to cancel their execution.

**Hint:** Think about the first fulfilled Promise.

### 16. What is the role of the Promise constructor?

- **It creates a new Promise where an executor function manually controls the resolve and reject calls** ✅
  - Promise constructor: executor runs immediately (synchronous). Resolve/reject called asynchronously.
- It is a specialized utility used to merge two existing Promises into a single new instance
  - The constructor is for creating Promises from scratch, not merging existing instances.
- It acts as a decorator that automatically adds timeout logic to any synchronous function
  - It does not provide automatic timeouts; these must be implemented inside the executor.
- It defines a template for asynchronous classes to ensure they implement a standard .then() method
  - The constructor creates instances; it is not an interface or template for class definitions.

**Hint:** Think about creating a new Promise manually.

### 17. What is Promise chaining?

- **A pattern where each .then() returns a new Promise, allowing for sequential async operations** ✅
  - Chaining: each .then() transforms value, returns new Promise. Prevents nesting.
- A method of linking multiple Promises together so they all resolve at exactly the same time
  - Chaining is about sequential order (one after another), not simultaneous resolution.
- A memory optimization that allows multiple Promises to share the same underlying result object
  - Each link in a chain is a distinct Promise instance with its own state and value.
- A security feature that prevents a Promise from being accessed by unauthorized scripts
  - Chaining is a control flow pattern and has no relationship to security or authorization.

**Hint:** Think about .then() returning a new Promise.

### 18. What is the unhandledrejection event?

- **A global event fired when a Promise is rejected and no rejection handler is attached to it** ✅
  - unhandledrejection: global safety net. Production safeguard.
- A syntax error triggered during development when a Promise constructor is missing an executor
  - Missing an executor causes an immediate TypeError, not an unhandledrejection event.
- A network event that occurs when a server fails to respond to a fetch request within the timeout
  - This results in a rejected Promise; the event only fires if that rejection is not caught.
- A cleanup routine that runs automatically to close connections when an async function crashes
  - This is not an automatic cleanup; the event is a notification for manual error logging.

**Hint:** Think about catching Promise errors.

### 19. What is the AbortController API?

- **An interface that allows you to abort one or more Web requests or asynchronous operations** ✅
  - AbortController: fetch(url, { signal }). Cleanup cancellation.
- A specialized debugger used to stop the execution of the event loop for inspection
  - AbortController manages specific tasks, it does not stop the entire JavaScript event loop.
- A resource management tool that automatically deletes old Promises from the memory heap
  - It cancels ongoing operations but does not directly manage garbage collection of objects.
- A middleware component used to reject incoming HTTP requests based on their payload size
  - This describes server-side request filtering, which is unrelated to the client-side AbortController.

**Hint:** Think about cancelling fetch/async operations.

### 20. What is the primary function of the Fetch API?

- **A modern, Promise-based interface for making network requests and handling responses** ✅
  - Fetch: modern replacement for XMLHttpRequest. 404/500 don't reject; check response.ok.
- A server-side utility used to scrape HTML content from external websites for indexing
  - Fetch is a general networking API, not a specialized library for web scraping or indexing.
- A synchronous data retrieval method that blocks code execution until a file is downloaded
  - Fetch is asynchronous and returns a Promise; it does not block the main execution thread.
- An internal browser routine that pre-loads images to improve the speed of page rendering
  - This describes prefetching or preloading hints, not the functional Fetch API used in code.

**Hint:** Think about Promise-based HTTP requests.

### 21. What is an async iterator?

- **An object that implements the Symbol.asyncIterator method for use with for-await-of loops** ✅
  - Async iterators: yield Promises. for-await-of waits each iteration. Streams, paginated APIs.
- A function that automatically iterates through an array and executes each item in parallel
  - Iterators process items one by one; parallel execution is handled by Promise.all().
- A specialized loop that allows synchronous functions to be executed inside an async context
  - Standard loops already allow this; async iterators specifically handle asynchronous sources.
- A data structure that stores asynchronous results in a first-in, first-out sequence
  - This describes a queue or buffer, not the iterator pattern for traversing data.

**Hint:** Think about for-await-of loops.

### 22. What is the difference between concurrent and sequential execution?

- **Concurrent runs independent tasks in parallel; sequential waits for each task to finish before starting the next** ✅
  - Concurrent faster when independent. Sequential for dependent operations or rate limiting.
- Concurrent is always safer for database writes; sequential is faster for read-only operations
  - Safety depends on transaction logic; concurrency is generally faster than sequential execution.
- Concurrent execution requires Web Workers; sequential execution is the only mode for the main thread
  - The main thread supports concurrency via the event loop and Promises without Web Workers.
- Concurrent refers to nested callbacks; sequential refers to the use of modern async/await syntax
  - Both syntaxes can represent both execution models; they are architectural choices, not syntax limits.

**Hint:** Think about Promise.all() vs awaiting one by one.

### 23. What is top-level await?

- **The ability to use the await keyword at the highest level of a module without an async function** ✅
  - Top-level await: only in modules. Blocks module loading. Useful for initialization.
- A performance optimization that lifts all await calls to the top of the call stack for faster execution
  - It is a syntax feature for module initialization, not a lifting optimization for the call stack.
- A specialized error handling mode that catches all rejections at the top level of the window object
  - This refers to global error listeners, not the top-level await syntax feature.
- A global setting that forces all functions in a script to act as if they were declared as async
  - JavaScript does not have a setting to globally change function types; types must be declared.

**Hint:** Think about await in module scope.

### 24. What is async context preservation?

- **Ensuring that "this" and other closure variables remain accessible across asynchronous boundaries** ✅
  - Context preservation: arrow functions preserve this, explicit .bind() for callbacks.
- A memory management technique that keeps local variables from being garbage collected
  - This describes closures generally; async context preservation specifically handles "this" binding.
- A security policy that prevents asynchronous functions from accessing the global window scope
  - Async functions have the same scope access as synchronous functions; no such policy exists.
- The practice of saving the current state of a Promise to a local file in case of a crash
  - This describes persistence or checkpointing, not architectural context preservation.

**Hint:** Think about context loss with async.

### 25. What is the retry pattern in asynchronous code?

- **A strategy of wrapping async calls in a loop with error handling and exponential backoff** ✅
  - Retry pattern: configurable delays, exponential backoff, jitter.
- A recursive function that re-executes itself immediately whenever any variable changes state
  - This describes reactive programming or observers, not a specific retry pattern for errors.
- A database configuration that automatically restores deleted records from a transaction log
  - This is a database recovery feature, whereas the retry pattern is an application-level logic.
- An optimization that caches successful results to avoid making the same request twice
  - This describes memoization or caching, which is the opposite of retrying a failed operation.

**Hint:** Think about retrying failed requests.

### 26. What is a typical use case for Promise.allSettled()?

- **Handling a batch of independent operations where partial success is acceptable and results must be tracked** ✅
  - allSettled: results include { status, value } or { status, reason }. Robust error handling.
- Ensuring that a critical sequence of financial transactions stops immediately if one step fails
  - This requires Promise.all() or strict sequential execution to prevent invalid states.
- Improving the performance of a single large file upload by splitting it into smaller chunks
  - While chunks can be sent in a batch, allSettled is for result tracking, not the splitting logic.
- Translating synchronous XML requests into a modern JSON format for use in older browsers
  - AllSettled is an ES2020 feature and is not a translation tool for legacy browser compatibility.

**Hint:** Think about batch operations with failures.

### 27. What is the purpose of debouncing an asynchronous operation?

- **To limit the rate at which a function executes by waiting for a period of inactivity before triggering** ✅
  - Async debounce: Reduces unnecessary API calls. Common: search input, window resize.
- To encrypt asynchronous data payloads before they are transmitted over a public network
  - Encryption is a security task; debouncing is a rate-limiting and performance optimization.
- To ensure that two different asynchronous operations do not access the same memory address
  - This describes mutexes or concurrency locks, not the debouncing of function calls.
- To automatically increase the priority of a Promise so it resolves faster under heavy load
  - Debouncing actually delays execution rather than increasing its speed or priority.

**Hint:** Think about delaying async operations.

### 28. How is Promise.then() return value transformed?

- **If the handler returns a value, the new Promise resolves to that value; if it returns a Promise, it waits for it** ✅
  - Then unwraps returned Promises. Return value wraps in Promise automatically.
- The return value is ignored, and the new Promise always resolves with the original value from the first Promise
  - Then handlers transform data; if they did not, chaining would not be useful for data processing.
- The return value is immediately converted into a string to ensure type safety in the next link of the chain
  - JavaScript does not force string conversion; the original type or returned type is preserved.
- Returning any value from a .then() block causes the entire Promise chain to reject with a TypeError
  - Returning values is the standard and expected behavior for successfully transforming async data.

**Hint:** Think about transforming Promise results.

### 29. What are asynchronous cleanup patterns?

- **Using try/finally blocks to ensure that resources like timers and connections are closed regardless of success** ✅
  - Finally always runs: resource cleanup, AbortController cleanup, listener removal. Prevents leaks.
- The use of a global garbage collector that identifies and deletes pending Promises every sixty seconds
  - Garbage collection is automatic but does not clean up active resources like open network sockets.
- A specialized syntax that automatically deletes all variables at the end of every async function
  - JavaScript relies on standard scoping; there is no special async-only variable deletion syntax.
- A process of overwriting sensitive data with null values before a Promise is allowed to settle
  - This describes a security/privacy pattern (data masking), not general resource cleanup.

**Hint:** Think about cleaning up resources in async code.

### 30. What are generator functions?

- **Functions that can be exited and later re-entered, with their context preserved across multiple re-entries** ✅
  - Generator: function* syntax. Yields values, returns iterator. Enables coroutines, lazy evaluation.
- Specialized constructors used to generate random data sets for performance and load testing
  - While they can generate data, the term refers to the pause/resume execution model of function*.
- An internal engine routine that generates optimized machine code from high-level JavaScript
  - This describes a JIT (Just-In-Time) compiler, not the generator function feature of the language.
- A type of asynchronous function that automatically parallelizes loops for increased performance
  - Generators are synchronous by default and yield control manually; they do not parallelize code.

**Hint:** Think about functions that can pause and resume.
