Synchronous vs asynchronous functions
By FrontendPro Editorial Team Updated 9/26/2026
Answer
Synchronous code blocks: each statement finishes before the next begins, so the order you read is the order it runs. Asynchronous code starts something and moves on, delivering the result later.
console.log("1");
setTimeout(() => console.log("2"), 0);
console.log("3");
// 1, 3, 2
Why it matters: one thread
JavaScript executes on a single thread, so a synchronous operation that takes a second freezes everything for that second — no rendering, no clicks, no scrolling. That is why anything slow (network requests, file access, database queries) is asynchronous: the work is handed off, the thread carries on, and a callback runs when the result is ready.
Note that async does not mean parallel. Your code still runs one piece at a time; it just interleaves rather than waiting.
How results come back
// callback — the original style
fs.readFile("a.txt", (err, data) => { /* ... */ });
// promise
fetch("/api/data").then((r) => r.json()).catch(handleError);
// async/await — same promises, written like synchronous code
async function load() {
const res = await fetch("/api/data");
return res.json();
}
await does not block the thread; it suspends that function and lets everything else continue.
Two things people get wrong
An async function always returns a promise, even if you return a plain value. And calling one without await starts the work but does not wait for it:
const data = load(); // a Promise, not the data
const data = await load(); // the data
Finally, a long synchronous loop inside an async function still blocks the page — async only helps when there is something real to wait for. For heavy computation you need a Web Worker, or to break the work into chunks that yield back to the event loop.
