Synchronous vs Asynchronous JavaScript
JavaScript is single-threaded — it can only execute one piece of code at a time. Synchronous code runs line by line, and each line must complete before the next begins. This works fine for simple logic, but when a task takes time (reading a file, fetching data from a server), synchronous execution would freeze the entire application.
The Event Loop
JavaScript's concurrency model is built on an event loop. The engine runs the current call stack to completion, then checks a queue of pending tasks (callbacks, promises, timers) and processes them one at a time. This allows JavaScript to handle I/O without threads.
Blocking vs Non-blocking
Synchronous operations that take a long time are called blocking — they prevent any other code from running. Asynchronous operations register a callback or return a promise and yield control back to the event loop, which can handle other tasks while waiting.
Why It Matters
In browsers, blocking the main thread freezes the UI — animations stutter, clicks go unregistered, and scroll becomes unresponsive. In Node.js, blocking the thread means no other requests can be served. Asynchronous patterns solve both problems.