Menu
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP W3.CSS C C++ C# HOW TO BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR ANGULARJS GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SWIFT SASS VUE GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING INTRO TO HTML & CSS BASH RUST TOOLS

JS Tutorial

JS Home JS Introduction JS Where To JS Output JS Syntax JS Operators JS If Conditions JS Loops JS Strings JS Numbers JS Functions JS Objects JS Scope JS Dates JS Temporal  New JS Arrays JS Sets JS Maps JS Iterations JS Math JS RegExp JS Data Types JS Errors JS Debugging JS Style Guide JS Reference JS Projects  New JS Versions JS HTML DOM JS HTML Events JS HTML First

JS Advanced

JS Functions JS Objects JS Classes JS Asynchronous JS Modules JS Meta & Proxy JS Typed Arrays JS DOM Navigation JS Windows JS Web API JS AJAX JS JSON JS jQuery JS Graphics JS Examples JS Reference


JavaScript Event Loop

JavaScript can only execute one piece of code at a time.

While JavaScript is busy, other JavaScript code must wait.

How do JavaScript handle timers, user clicks, downloads, and asynchronous operations?

The answer is the Event Loop.

Understanding the Event Loop

Understanding the Event Loop explains many common JavaScript behaviors.

  • Why setTimeout(..., 0) does not execute immediately.
  • Why long loops freeze a page.
  • Why Promises execute before timers.
  • Why await does not block the browser.
  • Why click events wait until current code has finished.

JavaScript Executes One Task at a Time

JavaScript executes code in sequence.

Only one function can execute at any given moment.

Each function must finish before the next one can begin.

Examples

function step1() {
  myDisplayer("Step 1");
}
function step2() {
  myDisplayer("Step 2");
}

step1();
step2();

Output:

Step 1
Step 2

Try it Yourself »

function step1() {
  myDisplayer("Step 1");
}
function step2() {
  myDisplayer("Step 2");
}

step1();
step2();

Output:

Step 2
Step 1

Try it Yourself »


The Browser Performs Asynchronous Work

JavaScript itself does not wait for timers or download web pages.

Instead, the browser performs these operations while JavaScript continues running.

Examples include:

  • Timers
  • Network requests
  • User events
  • File loading

When an operation finishes, JavaScript is notified that the result is ready.


The Event Loop

The Event Loop continuously checks whether JavaScript is busy.

When JavaScript finishes its current task, the Event Loop starts the next waiting task.

This process repeats for as long as the page is open.

JavaScript starts


Run code


Start timer


Continue running


Timer finishes


Event Loop


Run callback

The Event Loop coordinates asynchronous operations and decides when JavaScript should execute the next task.


Example: setTimeout()

The callback is not executed immediately.

Instead, it waits until JavaScript finishes its current work.

Example

myDisplayer("A");

setTimeout(function() {
  myDisplayer("B");
}, 2000);

myDisplayer("C");

Output:

A
C
B

Try it Yourself »

The timer finishes almost immediately.

However, the callback cannot run until JavaScript finishes executing the current code.

The Event Loop starts the callback after the current task has completed.


Example: Promise

Example

myDisplayer("A");

Promise.resolve().then(function() {
  myDisplayer("B");
});

myDisplayer("C");

Output:

A
C
B

Try it Yourself »

Why did the Promise callback run before the timer?

The answer is that Promise callbacks are placed in a special queue with higher priority.


Task Queue and Microtask Queue

JavaScript uses two main queues for asynchronous work.

Queue Contains
Task Queue Timers, events, messages
Microtask Queue Promise handlers and awai

After each task finishes, JavaScript processes all waiting microtasks before starting the next task.


Comparing Timers and Promises

OperationQueue
setTimeout()Task Queue
setInterval()Task Queue
Click eventTask Queue
Promise.then()Microtask Queue
catch()Microtask Queue
finally()Microtask Queue
await continuationMicrotask Queue

Long Tasks Block JavaScript

If JavaScript executes a long-running task, everything else must wait.

During this time, the browser cannot execute other JavaScript code.

User clicks, timers, and completed downloads must wait until the current task finishes.

Example

The browser becomes unresponsive while wait() is running.

function wait() {
  let i = 4e9;
  while (--i > 0);
}

myDisplayer("Start");
wait();
myDisplayer("Done");

Try it Yourself »

Example Explained

Why did the example take a long time?

Why was "Start" and "Done" diplayed at the same time?

The questions lead directly to how browsers update the page.

Example

The code executes like this:

myDisplayer("Start");
wait();
myDisplayer("Done");

Step 1

This code:

myDisplayer("Start");

changes the DOM:

<p id="demo">Start</p>

But the browser does not repaint the screen immediately.

Step 2

starts the long loop.
wait();

While this loop is running:

  • JavaScript is busy
  • The Event Loop cannot run
  • The browser cannot repaint the page

So although the DOM already contains "Start", the user still doesn't see it.

Step 3

The loop finally finishes.

myDisplayer("Done");

Now the DOM becomes:

<p id="demo">Start Done</p>

Step 4

The JavaScript task is finished.

Only now does the browser get a chance to repaint the page.

So the user sees:

Start Done

Diplayed both at once.

The Timeline

JavaScript starts


myDisplayer("Start")
(DOM changes)


wait()
(JavaScript busy)


myDisplayer("Done")
(DOM changes again)


JavaScript finishes


Browser repaints


Screen shows:
Start Done

The example above is a good Event Loop example.

It demonstrates that there are two separate things:

  • Updating the DOM
  • Updating the screen (rendering)

The DOM is updated immediately, but the browser must wait until the current JavaScript task has finished before repainting.


Want to show "Start" first?

Example

You have to give the browser a chance to repaint before running the long task:

function wait() {
  let i = 4e9;
  while (--i > 0);
}

myDisplayer("Start");

setTimeout(function () {
  wait();
  myDisplayer("Done");
}, 0);

Try it Yourself »

The Timeline

JavaScript starts


Display "Start"


Current task finishes


Browser repaints
(Start becomes visible)


Event Loop


Run wait()


Display "Done"


Browser repaints

Summary

  • JavaScript executes one task at a time.
  • The browser performs asynchronous operations such as timers, downloads, and user events.
  • Completed operations wait until JavaScript is ready.
  • The Event Loop starts waiting tasks when the current task has finished.
  • Promise handlers and await continuations run before timers because they use the Microtask Queue.

Visualizer »



×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
sales@w3schools.com

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
help@w3schools.com

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookies and privacy policy.

Copyright 1999-2026 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.

-->