Asynchronous/Synchronous Javascript
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
JavaScript is single-threaded — it runs one operation at a time on the main thread. Synchronous code blocks execution until each statement completes. Asynchronous code (callbacks, Promises, async/await) lets the engine start an operation, continue executing other code, and handle the result later when it is ready. Understanding this distinction is fundamental to writing performant JavaScript, especially for I/O operations like network requests, file reads, and timers.
Synchronous JavaScript
Synchronous code runs line by line. Each statement waits for the previous one to finish:
Blocking example:
Synchronous blocking is a problem in browsers because the main thread also handles rendering and user input. A long synchronous operation freezes the page.
Asynchronous JavaScript: Callbacks
The original async pattern — pass a function to be called when the operation completes:
setTimeout registers the callback and returns immediately. The engine continues to console.log("End"), then executes the callback when the timer expires.
Callback hell (the problem with nested callbacks):
Asynchronous JavaScript: Promises
Promises represent a future value — pending, fulfilled, or rejected:
Promises flatten callback nesting into a .then() chain. Errors propagate to the nearest .catch().
Asynchronous JavaScript: async/await
async/await is syntactic sugar over Promises that makes async code read like synchronous code:
await pauses execution of the async function (not the main thread) until the Promise resolves. Other code continues running during the pause.
The Event Loop
The event loop is the mechanism that enables async behavior in single-threaded JavaScript:
Microtasks (Promises) always execute before macrotasks (setTimeout), even if the setTimeout delay is 0.
Parallel vs Sequential Async
Use Promise.all() when operations are independent. Use sequential await when each operation depends on the previous result.
Promise Utilities
Common Pitfalls
- Forgetting
awaitbefore a Promise:const data = fetchUser(1)assigns the Promise object, not the resolved value. Withoutawait,datais a pending Promise and subsequent code operates on the wrong type. - Using
awaitin a regular (non-async) function:awaitis only valid insideasyncfunctions. Using it outside produces aSyntaxError. In top-level module code (ESM), top-levelawaitis allowed. - Sequential
awaitwhen parallel is possible:await fetchA(); await fetchB();takes the sum of both durations. If they are independent, useawait Promise.all([fetchA(), fetchB()])to run them concurrently. - Swallowing errors by not using
.catch()ortry/catch: Unhandled Promise rejections crash Node.js (since v15) and produce warnings in browsers. Always handle errors with.catch()ortry/catcharoundawait. - Blocking the event loop with synchronous code: A CPU-intensive synchronous operation (large loop, synchronous file read) blocks the entire event loop, preventing async callbacks from executing. Use
Web Workersorworker_threads(Node.js) for CPU-heavy tasks.
Summary
- Synchronous code blocks execution — each line waits for the previous one
- Asynchronous code (callbacks, Promises, async/await) starts operations and handles results later
async/awaitis the modern standard — reads like synchronous code but is non-blocking- The event loop processes microtasks (Promises) before macrotasks (setTimeout)
- Use
Promise.all()for parallel execution of independent async operations - Always handle errors with
try/catchor.catch()on Promises
Related reading
- asyncio awaitable object - basic example
- Asyncio terminating all tasks when one of them throws exception
- asyncio/aiohttp - How to make series of async - but dependent - requests?
- asyncio.gather vs asyncio.wait vs asyncio.TaskGroup
- avoid rebuilding node_modules in elastic beanstalk
- Avoiding Callback Hell with Multiple Meteor Method calls on Client
- asyncio.gather vs asyncio.wait vs asyncio.TaskGroup
- asyncio.run cannot be called from a running event loop when using Jupyter Notebook
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.