JavaScript Execution Model & Event Loop
JavaScript ek single-threaded, synchronous language hai. Matlab, ek samay par ek hi task ko run karti hai. Lekin jab hum JavaScript code likhte hain to humein aisa lagta hai ki wo multiple tasks ek saath execute kar rahi hai. Example ke liye, ek taraf API call chal rahi hai, doosri taraf setTimeout ke andar ka code run ho raha hai aur teesri taraf UI update ho raha hai.
Agar JavaScript ek hi thread par chalti hai to wo ek saath itne tasks kaise handle kar leti hai?
Iska jawab hai Event Loop & Queues (Macro-task aur Micro-task Queue).
JavaScript Execution Model :
JavaScript ke execution model ko samajhne ke liye humein sabse pehle samajhna hoga Call Stack kya hota hai:
Call Stack:
Ek stack-based data structure jismein JavaScript functions ka record rakhti hai. Jab bhi koi function call hota hai to wo stack ke top par add ho jaata hai (push hota hai). Jab wo function complete ho jaata hai, to wo stack se remove (pop) ho jaata hai.
Example :
function first() {
console.log("First function");
second();
}
function second() {
console.log("Second function");
}
first();
Execution Process:
- first() stack me gaya.
- console.log(“First function”) run hua.
- second() call hua → stack me gaya.
- console.log(“Second function”) run hua.
- second() complete → stack se pop.
- first() complete → stack se pop.
Is process ko Execution Context kehte hain.
Problem: Agar koi task bahut heavy hai (e.g. infinite loop ya heavy calculation), to stack busy ho jaata hai aur pura program freeze ho jaata hai. Isi wajah se asynchronous operations ko handle karne ke liye Event Loop aur Queues ka mechanism banaya gaya.
Event Loop Kya Hai ?
Event Loop ko ek bridge ya traffic police ki tarah samajh sakte ho. Iska kaam hai continuously ye check karna ki:
- Call Stack khaali hai ya busy?
- Agar Call Stack khaali hai to queue me rakhe tasks ko execute karna.
Event Loop ke bina JavaScript asynchronous tasks ko kabhi execute hi nahi kar paati, kyunki stack me ek hi waqt ek hi function execute ho sakta hai.
Example :
console.log("A");
setTimeout(() => {
console.log("B");
}, 1000);
console.log("C");
Output:
A
C
B
Explanation:
- Pehle “A” print hua (synchronous).
- Phir setTimeout ke callback ko queue me daal diya (1 second ke liye wait karega).
- “C” turant print ho gaya.
- 1 second ke baad Event Loop ne dekha stack empty hai → “B” run kara diya.
Yaha Event Loop ka role tha tasks ko right time par stack me bhejna.
Macro-task Queue :
Macro-task queue ek line ki tarah hoti hai jisme bade-bade asynchronous tasks rakhe jaate hain. Jab Call Stack free ho jaata hai, to Event Loop macro-task queue se ek task uthata hai aur stack me bhej deta hai.
Macro-task ke examples:
- setTimeout
- setInterval
- setImmediate (Node.js specific)
- I/O operations (file read, network request callbacks)
- UI rendering events (click, keypress etc.)
Example:
console.log("Start");
setTimeout(() => {
console.log("Inside Timeout");
}, 0);
console.log("End");
Output :
Start
End
Inside Timeout
Explanation:
- “Start” → stack me gaya aur print hua.
- setTimeout → 0 ms delay hone ke baad bhi callback ko queue me bhej diya (Macro-task Queue).
- “End” → stack me execute hua.
- Ab stack empty hua → Event Loop ne queue se task uthaya aur “Inside Timeout” run kar diya.
Even agar setTimeout(…, 0) lagao, tab bhi wo synchronous code ke baad hi chalega, kyunki wo Macro-task Queue me jata hai.
Micro-task Queue :
Micro-task queue ko aap ek VIP queue samajh lo. Ye hamesha Macro-task Queue se pehle execute hoti hai. Matlab Event Loop ka golden rule hai:
Pehle Micro-task Queue khali karo, uske baad Macro-task Queue par jao.
Micro-task ke examples:
- Promises (.then, .catch, .finally)
- Mutation Observer (DOM change tracking)
- process.nextTick() (Node.js specific)
Example :
console.log("Start");
setTimeout(() => {
console.log("Timeout");
}, 0);
Promise.resolve().then(() => {
console.log("Promise resolved");
});
console.log("End");
Output:
Start
End
Promise resolved
Timeout
Explanation:
- “Start” → synchronous, stack me run.
- setTimeout → Macro-task Queue me gaya.
- Promise.resolve().then() → Micro-task Queue me gaya.
- “End” → synchronous, run ho gaya.
- Ab Event Loop ne dekha: Stack empty hai → pehle Micro-task Queue clear karega → “Promise resolved”.
- Fir Macro-task Queue → “Timeout”.
Isliye Promises ka callback hamesha setTimeout se pehle execute hota hai.
Order :
JavaScript execution ka strict priority rule hota hai:
- Call Stack (Synchronous Code) – Sabse pehle normal functions aur code execute hota hai.
- Micro-task Queue – Promises ke callbacks, Mutation Observers, etc. Ye sab immediately next tick me execute ho jaate hain.
- Macro-task Queue – setTimeout, setInterval, I/O callbacks, etc. Ye sab tabhi execute hote hain jab stack aur Micro-task queue dono empty ho.
Example Scenarios
Scenario 1: Online Shopping Website
- User Add to Cart button click karta hai → UI ko turant update karna hai (Promise → Micro-task).
- Backend se stock availability check karna hai → thoda delay acceptable hai (setTimeout → Macro-task).
- Pehle UI update hota hai (kyunki Promise Micro-task Queue me tha), uske baad stock check ka response aata hai.
Scenario 2: Social Media App
- User post like karta hai → turant “Liked” dikhna chahiye (Micro-task).
- Server pe data save hone ka kaam baad me ho sakta hai (Macro-task).
- Ye hi reason hai ki Micro-tasks ko hamesha priority di jaati hai.
Code Execution Process :
- Code run → Call Stack me jata hai.
- Agar synchronous hai → turant execute ho jata hai.
- Agar asynchronous hai → Macro ya Micro Queue me chala jaata hai.
- Event Loop continuously check karta hai → Stack khaali hai to queue se task uthata hai.
- Micro-task Queue ke tasks hamesha Macro-task Queue se pehle execute hote hain.
Is process se JavaScript smooth aur non-blocking execution deti hai.
Key Points
- JavaScript ek single-threaded language hai, lekin Event Loop ke wajah se asynchronous tasks handle kar paati hai.
- Event Loop ek coordinator hai jo stack aur queues ko manage karta hai.
- Do tarah ki queues hoti hain:
- Macro-task Queue → setTimeout, setInterval, DOM events, I/O
- Micro-task Queue → Promises, Mutation Observer
- Micro-tasks ki priority Macro-tasks se hamesha zyada hoti hai.
- Is wajah se Promises ka callback hamesha setTimeout ke callback se pehle execute hota hai.
Important :
Event Loop ko ek restaurant waiter samajho.
- Customer (synchronous code) order karta hai → immediately serve hota hai.
- VIP guests (Micro-task queue) ka order hamesha priority se serve hota hai.
- Normal customers (Macro-task queue) ko VIP ke baad serve kiya jaata hai.
Is wajah se JavaScript asynchronous programming ko smartly handle karti hai.
Quiz: Test Your Knowledge on Event Loop & Microtask Queue in JavaScript
Bonus: Practical Application!
Aaj hi JavaScript Event Loop & Microtask Queue ka concept samajhkar apne asynchronous code ko aur predictable banayein!
Event Loop & Microtask Queue ko samajhne ke liye call stack, callback queue, microtasks, promises jaise concepts ka upayog karein. Ye concurrency model aur asynchronous execution ko samajhne ke liye bahut important hote hain. Inka use karke aap setTimeout, promises, async/await jaise features ko sahi tareeke se implement kar sakte hain aur apne code ko efficient aur bug-free bana sakte hain.