Asynchrony

Frontend SELF EN
Level 43 , Lesson 0
Available

1.1 Basic Concepts of Asynchrony

Asynchrony in JavaScript lets you perform tasks in the background without blocking the main execution thread. This is super important for tasks that can take a significant amount of time, like network requests, file reading, and timers. Let's delve into the main concepts of asynchronous programming in JavaScript and show some examples of its usage.

Single-threaded nature of JavaScript

JavaScript is a single-threaded language, meaning it executes code sequentially in one thread. However, asynchronous operations allow tasks to run in the background, freeing up the main thread for other tasks.

Event Loop

The Event Loop is a key mechanism that allows JavaScript to handle asynchronous tasks. The Event Loop manages the Message Queue and the Microtask Queue, ensuring the execution of asynchronous operations.

  1. Message Queue: contains tasks like event handlers, network requests, and timers. Tasks from this queue run sequentially.
  2. Microtask Queue: holds tasks with higher priority compared to tasks in the Message Queue. Examples include Promise resolutions and callbacks in microtasks.

The Event Loop constantly checks both queues and executes tasks from them when the main thread becomes free.

Asynchronous Operations

Asynchronous operations let tasks run in the background. Main examples of asynchronous operations include:

  • Timers (setTimeout, setInterval)
  • Event handlers
  • Network requests (like XMLHttpRequest, Fetch API)
  • File reading/writing (in Node.js)

Let's check out some examples of asynchronous operations.

1.2 Timers

Timers let you execute tasks with a delay or at regular intervals.

Example of using setTimeout

In this example, setTimeout sets up a function to execute after 2 seconds. So you first see Start and End, and then after 2 seconds, Executed after 2 seconds is logged.

JavaScript
    
      console.log('Start');

      setTimeout(() => {
        console.log('Executed after 2 seconds');
      }, 2000);

      console.log('End');
    
  

Example of using setInterval

In this example, setInterval runs a function every second, incrementing the counter and logging its value. When the counter hits 5, the interval is cleared using clearInterval:

JavaScript
    
      let counter = 0;

      const intervalID = setInterval(() => {
        counter++;
        console.log(`Counter: ${counter}`);
        if (counter >= 5) {
          clearInterval(intervalID);
        }
      }, 1000);
    
  

1.3 Event Handlers

Event handlers allow code execution in response to user actions or other events.

Example of using event handlers

In this example, a click event handler is added to a button. When the user clicks the button, the message Button clicked! is logged:

HTML
    
      <!DOCTYPE html>
      <html>
        <head>
          <title>Event Handler Example</title>
        </head>
        <body>
          <button id="myButton">Click me</button>

          <script>
            const button = document.getElementById('myButton');

            button.addEventListener('click', () => {
              console.log('Button clicked!');
            });
          </script>
        </body>
      </html>
    
  

1.4 Network Requests

Network requests let you perform asynchronous HTTP requests to a server.

Example of using XMLHttpRequest

In this example, an asynchronous GET request to an API is made, and when the request completes, the response is logged to the console:

JavaScript
    
      const xhr = new XMLHttpRequest();
      xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);

      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
          const response = JSON.parse(xhr.responseText);
          console.log(response);
        }
      };

      xhr.send();
    
  

1.5 Event Loop in Action

To better understand how the Event Loop works, let's check out the following example:

JavaScript
    
      console.log('Start');

      setTimeout(() => {
        console.log('Timeout 1');
      }, 0);

      Promise.resolve().then(() => {
        console.log('Promise 1');
      });

      setTimeout(() => {
        console.log('Timeout 2');
      }, 0);

      Promise.resolve().then(() => {
        console.log('Promise 2');
      });

      console.log('End');
    
  

Expected output will be:

  • Start
  • End
  • Promise 1
  • Promise 2
  • Timeout 1
  • Timeout 2

In this example, synchronous operations (console.log('Start') and console.log('End')) run first. Then, microtasks (Promise handlers) execute, and only after that, tasks from the Message Queue (setTimeout) are processed.

1
Task
Frontend SELF EN, level 43, lesson 0
Locked
Timers and Intervals
Timers and Intervals
1
Task
Frontend SELF EN, level 43, lesson 0
Locked
Event Loop Order
Event Loop Order
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION