Understand the Asynchronous JavaScript: Callbacks, Promises, and Async/Await
Tags: javascript, webdev, tutorial, programming
Published: 2023-04-15 15:17:09

<!-- wp:heading -->
<h2 class="wp-block-heading">What is Synchronous Programming?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Synchronous programming is a programming paradigm where operations or tasks are executed sequentially, one after the other. In this model, a task must complete its execution before the next task can start. The flow of control follows a linear path, and the program execution is blocked until the current task is finished.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Synchronous programming is straightforward and easy to understand since the code executes in the order it is written. However, it can lead to performance issues in cases where a task takes a long time to complete, such as waiting for a server response or reading a large file. While the program is waiting for the task to complete, it is blocked and unable to perform any other tasks.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">How to Create a Sync Programming in JavaScript</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Here is a simple example of synchronous programming in JavaScript:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>function task1() {
  console.log('Task 1');
}

function task2() {
  console.log('Task 2');
}

function task3() {
  console.log('Task 3');
}

task1();
task2();
task3();</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In this example, the functions <strong>task1</strong>, <strong>task2</strong>, and <strong>task3</strong> are executed in the order they are called. The output will be:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>Task 1
Task 2
Task 3</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Although synchronous programming can be suitable for simple tasks and small programs, it may not be efficient for more complex applications where tasks can be time-consuming or depend on external resources. In such cases, asynchronous programming can be used to improve performance and responsiveness.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What is Asynchronous Programming?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Asynchronous programming is a programming paradigm that allows multiple tasks to be executed concurrently without blocking the flow of program execution. In this model, tasks can start, run, and complete in overlapping time periods, enabling the program to continue processing other tasks while waiting for a long-running task to complete.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Asynchronous programming is particularly useful in situations where a task may take a long time to complete, such as waiting for a server response, reading a large file, or performing a complex computation. By allowing the program to continue executing other tasks while waiting for these time-consuming operations, asynchronous programming can lead to more efficient and responsive applications.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In JavaScript, asynchronous programming is commonly achieved through the use of callbacks, Promises, and the async/await syntax. These techniques allow the program to perform tasks concurrently without blocking the main thread, which is responsible for managing the user interface and other tasks.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">How to Create an Async Programming in JavaScript</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Here's a simple example of asynchronous programming in JavaScript using the <strong>setTimeout</strong> function:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>function task1() {
  console.log('Task 1');
}

function task2() {
  console.log('Task 2');
}

function task3() {
  console.log('Task 3');
}

task1();
setTimeout(task2, 1000); // Execute task2 after a 1000ms delay
task3();</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In this example, <strong>task1</strong> and <strong>task3</strong> are executed synchronously, while <strong>task2</strong> is executed asynchronously after a delay of 1000 milliseconds. The output will be:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>Task 1
Task 3
Task 2</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Notice that <strong>task3</strong> is executed before <strong>task2</strong>, even though <strong>task2</strong> is called before <strong>task3</strong> in the code. This is because <strong>task2</strong> is scheduled for execution after a delay, allowing the program to continue executing other tasks without waiting for <strong>task2</strong> to complete.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">How Callbacks Work in JavaScript</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Callback functions are functions that are passed as arguments to another function and are executed at a later time. They are particularly useful in asynchronous programming, as they allow us to specify what should happen when an asynchronous operation is completed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Callbacks are a way to manage the flow of your program when dealing with asynchronous events. By passing a function as an argument, you can ensure that the function is only called when the asynchronous operation is finished.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"textAlign":"start","level":3,"className":"has-text-align-start"} -->
<h3 class="wp-block-heading has-text-align-start">Create an Example with a Callback Function</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Let's create a simple example to demonstrate how callback functions work. We will create a <strong>getUser</strong> function that takes a user ID and a callback function as arguments. The <strong>getUser</strong> function will simulate an asynchronous operation using <strong>setTimeout</strong> and execute the callback function with the user data after a delay.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>// Define the getUser function, which takes a userId and a callback function as arguments
function getUser(userId, callback) {
  // Simulate an asynchronous operation using setTimeout
  setTimeout(() =&gt; {
    // Create a mock user object with the provided userId
    const user = {
      id: userId,
      name: 'John Doe',
    };

    // Call the callback function with the user object after a delay
    callback(user);
  }, 1000);
}

// Call the getUser function with a user ID and a callback function to handle the user data
getUser(1, user =&gt; {
  // This function will be executed after the getUser function completes its asynchronous operation
  console.log(`User ID: ${user.id}, User Name: ${user.name}`);
});</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In this example, we use the <strong>setTimeout</strong> function to simulate an asynchronous operation. The <strong>getUser</strong> function takes a <strong>userId</strong> and a <strong>callback</strong> function as arguments. After a 1-second delay, the callback function is executed with the user data.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">When we call the <strong>getUser</strong> function, we pass it a user ID and a callback function that will handle the user data. In this case, the callback function simply logs the user's ID and name to the console.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">The key takeaway from this example is that the callback function allows us to manage the flow of our program when dealing with asynchronous operations, such as fetching data from an API or reading data from a file.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"textAlign":"start","className":"has-text-align-start"} -->
<h2 class="wp-block-heading has-text-align-start">Callbacks - Revisiting setTimeout</h2>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">We will revisit the <strong>setTimeout</strong> function and show how it uses callback functions to execute code after a specified delay.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"textAlign":"start","level":3,"className":"has-text-align-start"} -->
<h3 class="wp-block-heading has-text-align-start">How setTimeout Uses Callback Functions</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">The <strong>setTimeout</strong> function is a built-in JavaScript function that allows you to execute a function after a specified delay. It takes two arguments:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li><p>A callback function that will be executed after the delay</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p>The delay time in milliseconds</p></li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Here's a simple example of using <strong>setTimeout</strong> with a callback function:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>// Define a callback function to be executed after a delay
function delayedFunction() {
  console.log('This message is displayed after a 2-second delay');
}

// Use setTimeout to execute the delayedFunction after 2000 milliseconds (2 seconds)
setTimeout(delayedFunction, 2000);</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In this example, we define a <strong>delayedFunction</strong> that simply logs a message to the console. We then use <strong>setTimeout</strong> to execute this function after a 2-second delay.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">The key takeaway here is that <strong>setTimeout</strong> uses a callback function to allow you to specify what code should be executed after the delay. This is a simple but powerful concept that enables you to control the flow of your program when dealing with asynchronous operations.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">You can also use anonymous functions as callback functions with <strong>setTimeout</strong>. Here's an example of using an anonymous function with <strong>setTimeout</strong>:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>// Use setTimeout to execute an anonymous function after 3000 milliseconds (3 seconds)
setTimeout(function() {
  console.log('This message is displayed after a 3-second delay');
}, 3000);</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In this case, we provide an anonymous function as the callback for <strong>setTimeout</strong>. This function is executed after a 3-second delay, and it logs a message to the console.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Callbacks - Revisiting array.filter</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Now we will revisit the <strong>array.filter</strong> method and explain how it uses callback functions to filter array elements based on a specified condition.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"textAlign":"start","level":3,"className":"has-text-align-start"} -->
<h3 class="wp-block-heading has-text-align-start">How array.filter Uses Callback Functions</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">The <strong>filter</strong> method is an array method in JavaScript that allows you to create a new array with elements that pass a specified test (a callback function). The callback function takes an array element as an argument and returns a boolean value. If the callback function returns <strong>true</strong>, the element is included in the new array; otherwise, it is excluded.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Here's an example of using <strong>array.filter</strong> with a callback function:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const numbers = &#91;1, 2, 3, 4, 5];

// Define a function that will be used as callback function to returns true if the number is even
function isEven(number) {
  return number % 2 === 0;
}

// Use array.filter to create a new array with only the even numbers
const evenNumbers = numbers.filter(isEven);

console.log(evenNumbers); // Output: &#91;2, 4]
</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"textAlign":"start","level":3,"className":"has-text-align-start"} -->
<h3 class="wp-block-heading has-text-align-start">Make your Own filterArray Function</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Now let's create a custom <strong>filterArray</strong> function that uses callback functions to filter elements in an array.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>// Define a custom filterArray function that takes an array and a callback function as arguments
function filterArray(array, callback) {
  const newArray = &#91;];

  for (const element of array) {
    if (callback(element)) {
      newArray.push(element);
    }
  }

  return newArray;
}</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"textAlign":"start","level":3,"className":"has-text-align-start"} -->
<h3 class="wp-block-heading has-text-align-start">Put the Custom filterArray Function to Use</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Now that we have our custom <strong>filterArray</strong> function, let's apply it to an array to demonstrate its functionality.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const numbers = &#91;1, 2, 3, 4, 5];

// Define a callback function that returns true if the number is greater than 3
function greaterThanThree(number) {
  return number &gt; 3;
}

// Use our custom filterArray function to create a new array with numbers greater than 3
const numbersGreaterThanThree = filterArray(numbers, greaterThanThree);

console.log(numbersGreaterThanThree); // Output: &#91;4, 5]</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">See, we use our custom <strong>filterArray</strong> function to create a new array with numbers greater than 3. We define a <strong>greaterThanThree</strong> callback function that takes a number and returns <strong>true</strong> if the number is greater than 3. We then pass this callback function to our <strong>filterArray</strong> function, along with the original <strong>numbers</strong> array.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Experiment: What if fetch Used Callbacks?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">We will discuss the challenges of using callbacks with the <strong>fetch</strong> function. We'll consider an alternative scenario where <strong>fetch</strong> uses callback functions instead of Promises, which are used by the actual <strong>fetch</strong> implementation.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"textAlign":"start","level":3,"className":"has-text-align-start"} -->
<h3 class="wp-block-heading has-text-align-start"><strong>T</strong>he Cddddhallenges of Using Callbacks with fetch</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">The <strong>fetch</strong> function is a modern, built-in JavaScript function for making HTTP requests. It returns a Promise that resolves to the Response object representing the response to the request.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Let's imagine a scenario where <strong>fetch</strong> uses callback functions instead of Promises:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>function fetchWithCallback(url, successCallback, errorCallback) {
  // Simulate the fetch functionality using callbacks
  // This example is for illustration purposes only
}

fetchWithCallback(
  'https://api.example.com/data',
  function (data) {
    console.log('Success:', data);
  },
  function (error) {
    console.error('Error:', error);
  }
);</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In this example, we create a hypothetical <strong>fetchWithCallback</strong> function that takes a URL and two callback functions: a <strong>successCallback</strong> that is called when the request succeeds, and an <strong>errorCallback</strong> that is called when the request fails.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">The main challenge with using callbacks in this scenario is handling complex asynchronous flows, such as making multiple requests in a sequence or handling errors. Callbacks can lead to a situation known as "callback hell," where nested callbacks become hard to read, understand, and maintain.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">For example, imagine that you need to make three sequential requests using the <strong>fetchWithCallback</strong> function:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>fetchWithCallback(
  'https://api.example.com/data1',
  function (data1) {
    // Process data1
    fetchWithCallback(
      'https://api.example.com/data2',
      function (data2) {
        // Process data2
        fetchWithCallback(
          'https://api.example.com/data3',
          function (data3) {
            // Process data3
          },
          function (error3) {
            console.error('Error fetching data3:', error3);
          }
        );
      },
      function (error2) {
        console.error('Error fetching data2:', error2);
      }
    );
  },
  function (error1) {
    console.error('Error fetching data1:', error1);
  }
);</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">As you can see, the code quickly becomes difficult to read and understand due to the deeply nested callbacks. This is one of the main reasons why Promises were introduced as a way to handle asynchronous operations in JavaScript. While this example works, it highlights some challenges of using callbacks with <strong>fetch</strong>, these challenges are:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li><p><strong>Callback Hell</strong>: As the number of asynchronous operations increases, the code can become deeply nested, making it difficult to read and maintain. This is known as "callback hell."</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p><strong>Error Handling</strong>: With callbacks, error handling becomes more complex, as each callback function needs to handle errors separately. In contrast, Promises allow for centralized error handling using <strong>.catch()</strong> or <strong>.finally()</strong> methods.</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p><strong>Composition</strong>: Promises make it easy to compose multiple asynchronous operations using methods like <strong>Promise.all()</strong>, <strong>Promise.race()</strong>, and <strong>Promise.allSettled()</strong>. Achieving the same level of composition with callbacks can be cumbersome and challenging.</p></li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In the actual <strong>fetch</strong> implementation and real-world scenario, which uses Promises, the same example would look like this:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>fetch('https://api.example.com/data1')
  .then((response1) =&gt; response.json())
  .then((data1) =&gt; {
    console.log('Data from the first request:', data1);

    return fetch('https://api.example.com/data2');
  })
  .then((response2) =&gt; response.json())
  .then((data2) =&gt; {
    console.log('Data from the second request:', data2);

    return fetch('https://api.example.com/data3');
  })
  .then((response3) =&gt; response.json())
  .then((data3) =&gt; {
    console.log('Data from the third request:', data3);
  })
  .catch((error) =&gt; {
    console.error('Error fetching data:', error);
  });
</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>So we first fetch data from '<strong>https://api.example.com/data1</strong>'. After the first request is successful, we log the data and proceed to make a second request to <strong>'https://api.example.com/data2</strong>'. Similarly, when the second request is successful, we log the data and make a third request to '<strong>https://api.example.com/data3</strong>'.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Finally, after the third request is successful, we log the data. If any error occurs during any of the requests, we handle it in the <strong>.catch()</strong> block.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>While it's possible to use callbacks with <strong>fetch</strong>, Promises offer a more elegant, readable, and maintainable approach to handling asynchronous operations like fetching data from an API.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What Are Promises and How Promises Work in JavaScript</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Promises are a powerful feature in JavaScript that helps manage asynchronous operations more effectively. A Promise represents the eventual completion (or failure) of an asynchronous operation and its resulting value. A Promise is in one of three states:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li><p><strong>Pending</strong>: The initial state; the Promise is neither fulfilled nor rejected.</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p><strong>Fulfilled</strong>: The operation was completed successfully, and the Promise has a resulting value.</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p><strong>Rejected</strong>: The operation failed, and the Promise has a reason for the failure.</p></li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Promises help to avoid the "callback hell" problem by providing a cleaner and more maintainable way to handle asynchronous code.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"textAlign":"start","level":3,"className":"has-text-align-start"} -->
<h3 class="wp-block-heading has-text-align-start">How they improve asynchronous programming</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Promises improve asynchronous programming by:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><p>Simplifying error handling through chaining and centralized error management.</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p>Making it easier to compose and manage multiple asynchronous operations.</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p>Improving code readability and maintainability by avoiding nested callbacks.</p></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Promises and .then() chaining:</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Promises allow you to chain <strong>.then()</strong> methods for handling the results of asynchronous operations. When a Promise is fulfilled, the next <strong>.then()</strong> method gets in.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Let's explore a deeper example of chaining <strong>.then()</strong> methods with Promises using the <strong>fetch</strong> function to make API requests.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Consider a scenario where we need to fetch data from two different API endpoints. The second API call depends on the data received from the first API call. We can use Promises and <strong>.then()</strong> chaining to achieve this.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In this example, we'll use the JSONPlaceholder API to fetch a user's information and then fetch the user's posts.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const fetch = require("node-fetch");
// Fetch user data from the JSONPlaceholder API
fetch('https://jsonplaceholder.typicode.com/users/1')
  .then((response) =&gt; {
    // Check if the request was successful
    if (!response.ok) {
      throw new Error('Failed to fetch user data');
    }
    // Parse the JSON data from the response
    return response.json();
  })
  .then((user) =&gt; {
    console.log('User data:', user);

    // Fetch the user's posts using their ID
    return fetch(`https://jsonplaceholder.typicode.com/posts?userId=${user.id}`);
  })
  .then((response) =&gt; {
    // Check if the request was successful
    if (!response.ok) {
      throw new Error('Failed to fetch user posts');
    }
    // Parse the JSON data from the response
    return response.json();
  })
  .then((posts) =&gt; {
    console.log('User posts:', posts);
  })
  .catch((error) =&gt; {
    // Handle any errors during the fetch operations
    console.error('Error:', error);
  });</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">We first fetch the user data from the JSONPlaceholder API. When the first request is successful, we parse the JSON data and log the user information. Next, we use the user's ID to fetch their posts. When the second request is successful, we parse the JSON data and log the user's posts. If an error occurs during any of the fetch operations, we handle it in the <strong>.catch()</strong> block.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">How to Use <code>Promise.all()</code> and Handle Rejected Promises</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>Promise.all()</strong> is a method that takes an array (or any iterable) of Promises and returns a new Promise that is fulfilled with an array of the fulfilled values of the input Promises, in the same order as the input Promises. The returned Promise is fulfilled only when all input Promises are fulfilled, and it is rejected if any of the input Promises are rejected.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Here's how you can use <strong>Promise.all()</strong>:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li><p>Create an array (or any iterable) of Promises.</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p>Pass the iterable to <strong>Promise.all()</strong>.</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p>Use <strong>.then()</strong> to handle the array of fulfilled values, or <strong>.catch()</strong> to handle rejection.</p></li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Let's look at an example using <strong>Promise.all()</strong> with the <strong>fetch</strong> function to make multiple API requests:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const fetch = require("node-fetch");
// An array of URLs to fetch
const urls = &#91;
  'https://jsonplaceholder.typicode.com/users/1',
  'https://jsonplaceholder.typicode.com/users/2',
  'https://jsonplaceholder.typicode.com/users/3',
];

// Create an array of Promises using fetch()
const fetchPromises = urls.map((url) =&gt; fetch(url));

// Use Promise.all() to wait for all fetch() Promises to be fulfilled
Promise.all(fetchPromises)
  .then((responses) =&gt; {
    // Map the responses to Promises that resolve with the parsed JSON data
    return Promise.all(responses.map((response) =&gt; response.json()));
  })
  .then((users) =&gt; {
    console.log('Fetched users:', users);
  })
  .catch((error) =&gt; {
    console.error('Error fetching users:', error);
  });</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">In this example, we have an array of URLs to fetch user data. We create an array of Promises using <strong>fetch()</strong> for each URL. Let's now take a look at more advanced techniques to handle asynchronous code in Javascript.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The Async/await keywords?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Async/await is a more modern and syntactically cleaner way of working with asynchronous code in JavaScript. It is built on top of Promises and makes your asynchronous code look and behaves more like synchronous code.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Async:</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">The <strong>async</strong> keyword is used to declare an asynchronous function. When a function is marked with <strong>async</strong>, it automatically returns a Promise. If the function returns a value, the Promise resolves with that value. If the function throws an error, the Promise is rejected with that error.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const fetch = require("node-fetch");
async function asyncFunction() {
  return 'Hello, async!';
}

asyncFunction()
  .then((result) =&gt; console.log(result)) // "Hello, async!"
  .catch((error) =&gt; console.error(error));</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Await:</h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">The <strong>await</strong> keyword can only be used inside an <strong>async</strong> function. It pauses the execution of the function until the Promise is resolved or rejected, and then resumes the execution of the function with the resolved value or throws the rejection reason.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Using <strong>await</strong> allows you to write asynchronous code that looks and behaves more like synchronous code, making it easier to read and understand.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Here's an example of using async/await with the <strong>fetch</strong> function to make an API request:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const fetch = require("node-fetch");
async function fetchUserData() {
  try {
    // Fetch user data from the JSONPlaceholder API
    const response = await fetch('https://jsonplaceholder.typicode.com/users/1');

    // Check if the request was successful
    if (!response.ok) {
      throw new Error('Failed to fetch user data');
    }

    // Parse the JSON data from the response
    const user = await response.json();
    console.log('User data:', user);
 
} catch (error) {
    // Handle any errors during the fetch operation
    console.error('Error:', error);
    }
}

// Call the fetchUserData function
fetchUserData();</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>We declare an `async` function called `fetchUserData()`. Inside this function, we use the `await` keyword to wait for the `fetch` request to resolve before continuing. We then check if the request was successful and parse the JSON data from the response using `await` as well. If an error occurs during any of the fetch operations, we handle it in the `catch` block. The async/await pattern makes the code easier to read and understand by removing the need for `.then()` and `.catch()` chaining. It allows you to write more linear, synchronous-looking code while still maintaining the benefits of asynchronous operations. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Note that although async/await makes your code look synchronous, it is still non-blocking and asynchronous under the hood. The JavaScript event loop continues to run, and other tasks can still be executed while the async function is waiting for Promises to resolve.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Async/Await in Loops</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>It's a common scenario where you need to execute multiple asynchronous operations sequentially, but you also want to use loops to simplify the code. Using async/await in synchronous loops can be a bit tricky, as using <strong>await</strong> within a regular <strong>for</strong> or <strong>forEach</strong> loop would not work as expected.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">We'll discuss how to properly use <a href="https://zellwk.com/blog/async-await-in-loops/" target="_blank" rel="noreferrer noopener">async/await with loops</a> and provide examples to demonstrate the correct and incorrect approaches.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"textAlign":"start","level":3,"className":"has-text-align-start"} -->
<h3 class="wp-block-heading has-text-align-start">Incorrect Approach with forEach:</h3>
<!-- /wp:heading -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const fetch = require("node-fetch");
async function fetchAllUsers(users) {
  users.forEach(async (userId) =&gt; {
    const user = await fetchUserData(userId);
    console.log('User data:', user);
  });

  console.log('Finished fetching all users');
}

fetchAllUsers(&#91;1, 2, 3, 4]);
</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">The <strong>forEach</strong> loop will execute all async functions concurrently, and you'll see the "Finished fetching all users" message before all the user data is fetched and logged.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"textAlign":"start","level":3,"className":"has-text-align-start"} -->
<h3 class="wp-block-heading has-text-align-start">Correct Approach with for...of loop:</h3>
<!-- /wp:heading -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const fetch = require("node-fetch");
async function fetchUserData(userId) {
  const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);

  if (!response.ok) {
    throw new Error('Failed to fetch user data');
  }

  return await response.json();
}

async function fetchAllUsers(users) {
  for (const userId of users) {
    const user = await fetchUserData(userId);
    console.log('User data:', user);
  }

  console.log('Finished fetching all users');
}

fetchAllUsers(&#91;1, 2, 3, 4]);</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">We use a <strong>for...of</strong> loop to execute the async <strong>fetchUserData()</strong> function sequentially for each user ID. The "Finished fetching all users" message will be logged only after all the user data has been fetched and logged.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Using a <strong>for...of</strong> loop or a regular <strong>for</strong> loop allows you to properly use <strong>await</strong> within the loop body, ensuring that each iteration of the loop waits for the previous asynchronous operation to complete before moving to the next. This brings that question to mind.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Correct Approach with <code>map()</code> and <code>Promise.all()</code>:</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A common use case for combining async/await with <code>map()</code> is when you want to make multiple asynchronous requests and wait for all of them to finish before processing the results. In such cases, you can use <code>Promise.all()</code> along with <code>map()</code> and async/await.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Here's an example of using async/await with <code>map()</code> and <code>Promise.all()</code>:</p>
<!-- /wp:paragraph -->

<!-- wp:prismatic/blocks -->
<pre class="wp-block-prismatic-blocks"><code class="language-">const fetch = require("node-fetch");

async function fetchUser(userId) {
  const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
  const user = await response.json();
  return user;
}

async function fetchMultipleUsers() {
  const userIds = [1, 2, 3, 4, 5];

  const userPromises = userIds.map(async (userId) => {
    const user = await fetchUser(userId);
    return user;
  });

  const users = await Promise.all(userPromises);
  console.log(users);
}

fetchMultipleUsers();
</code></pre>
<!-- /wp:prismatic/blocks -->

<!-- wp:paragraph -->
<p>In this example, we have an async function <code>fetchUser()</code> that fetches a user from the JSONPlaceholder API. We also have an async function <code>fetchMultipleUsers()</code> that fetches multiple users using the <code>fetchUser()</code> function.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Inside <code>fetchMultipleUsers()</code>, we use the <code>map()</code> function to create an array of Promises by calling <code>fetchUser()</code> for each user ID. Then, we use <code>Promise.all()</code> to wait for all Promises to resolve before logging the result.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Is the Async/Await in Loops as same as using <code>Promise.all()</code> ?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No, the <strong>Promise.all()</strong> approach and the "Asynchronous Awaits in Synchronous Loops" approach serve different purposes and are not the same.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start"><strong>Promise.all():</strong> When you want to execute multiple asynchronous operations concurrently, meaning you want them to run at the same time and wait for all the operations to complete before proceeding, you would use <strong>Promise.all()</strong>. It takes an array of promises and returns a new promise that resolves with an array of resolved values in the same order as the input promises.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start"><strong>Asynchronous Awaits in Synchronous Loops:</strong> When you want to execute multiple asynchronous operations sequentially, meaning you want each operation to complete before moving on to the next one, you would use the correct approach for "Asynchronous Awaits in Synchronous Loops" (using async/await with a <strong>for...of</strong> loop or a regular <strong>for</strong> loop).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Here's a summary of the differences:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li><p><strong>Promise.all()</strong> is used for concurrent execution of multiple promises, while async/await in synchronous loops is used for sequential execution of multiple promises.</p></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><p><strong>Promise.all()</strong> returns a single promise that resolves when all input promises have resolved or rejects if any of the input promises reject, whereas async/await in synchronous loops allows you to handle errors individually for each promise within the loop.</p></li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">Note that you would choose between these approaches based on whether you need concurrent or sequential execution of your asynchronous operations.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:image {"align":"center"} -->
<figure class="wp-block-image aligncenter"><img src="https://nerdleveltech.com/wp-content/uploads/ce7126ba-1daa-4fd4-bcb5-1ce543768e32.png" alt="data, analysis, accountant"/></figure>
<!-- /wp:image -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Conclusion:</h2>
<!-- /wp:heading -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">We explored the intricacies of asynchronous JavaScript programming, understanding callbacks, promises, and the async/await syntax. We also discussed how to handle common challenges when working with these concepts, such as using async/await in synchronous loops.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"start","className":"has-text-align-start"} -->
<p class="has-text-align-start">These concepts enable developers to write cleaner, more readable, and maintainable code when dealing with asynchronous operations, ultimately leading to a better programming experience and more robust applications.</p>
<!-- /wp:paragraph -->