What does "non-blocking code" mean?
1. What "blocking code" means
"Blocking" is code that does not release the main thread until it finishes.
While the operation runs, JavaScript cannot do anything else: it cannot handle clicks, repaint the interface, or run the next functions.
Example (blocking code):
// Simulating a long calculation
function heavyCalculation() {
const start = Date.now();
while (Date.now() - start < 3000) {} // wait 3 seconds
console.log("Calculation finished");
}
console.log("Start");
heavyCalculation();
console.log("End");Result:
Start
(hangs for 3 seconds)
Calculation finished
EndEverything froze for 3 seconds; the interface "froze", the server stops responding. This is blocking code.
2. What "non-blocking code" means
"Non-blocking" is code that does not stop the thread's execution, but delegates long operations (I/O, network, timers, files) and continues running other tasks.
Example (non-blocking):
console.log("Start");
setTimeout(() => {
console.log("1 second has passed");
}, 1000);
console.log("End");What happens:
- JS calls
setTimeout, handing the task off to the browser (Web API). - It continues executing (
"End"is printed right away). - After 1 second, the callback returns to the task queue and runs.
Result:
Start
End
1 second has passedThe code did not block the thread. JS freely handled other events while the timer "ran in the background".
3. Why this matters in JavaScript
JavaScript is single-threaded, meaning:
- at any given moment, only one piece of code runs;
- if one piece "hangs", everything else waits.
To avoid "hangs", JS uses:
- asynchrony (
setTimeout,fetch,async/await); - external APIs (Web APIs / the libuv thread pool);
- the event loop, to return the result once it is ready.
4. Examples of non-blocking operations
| Operation type | Example | What it does |
|---|---|---|
| Timers | setTimeout, setInterval | run later |
| Network | fetch, XMLHttpRequest | wait for a server response in the background |
| Files (Node.js) | fs.readFile | read the disk asynchronously |
| DB queries | db.query | wait for the result without blocking |
| Event listeners | addEventListener('click') | fire on an event |
| Promises | Promise, async/await | defer execution until the operation finishes |
5. An example of the difference in Node.js
The blocking version
const fs = require('fs');
console.log('Reading the file...');
const data = fs.readFileSync('large.txt', 'utf8'); // blocks the thread
console.log('File read:', data.length);While the file is being read, the server does not serve other requests.
The non-blocking version
const fs = require('fs');
console.log('Reading the file...');
fs.readFile('large.txt', 'utf8', (err, data) => {
console.log('File read:', data.length);
});
console.log('Other code is running...');Node.js hands the task off to the system (I/O) and keeps running. When the file is ready, the callback returns through the event loop.
6. Why "non-blocking" is not the same as "parallel"
This is a common interview mistake:
"Non-blocking code" does not mean everything runs in parallel.
JS still runs one callback at a time, but it does not waste time waiting on I/O. Meanwhile, the engine handles other tasks, which creates the impression of parallelism.
7. In short: blocking vs non-blocking
| Type | What it does | Example | Consequence |
|---|---|---|---|
| Blocking | Stops the thread until it finishes | fs.readFileSync() | The UI / server hangs |
| Non-blocking | Delegates the task, keeps running | fs.readFile() / fetch() | High responsiveness |
Summary
Non-blocking code is a way of writing programs where long operations (I/O, network, timers) run asynchronously, without interfering with the main logic or "freezing" the thread.
It underpins:
- JS asynchrony (
callbacks,promises,async/await); - Node.js performance;
- smooth interfaces in the browser.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.