Asynchronous programing

Asynchronous programing

·

4 min read

Asynchronous programming is a fundamental concept in JavaScript that allows you to run multiple operations at the same time without blocking the execution of the rest of your code. This is achieved through the use of callback functions, Promises, async/await, generators, and web workers.

There are several ways to perform async operations in JavaScript, such as:

  • Callbacks: a function that is passed as an argument to another function and executed when the async operation completes.

  • Promises: an object that represents the eventual completion or failure of an async operation, and its resulting value. It has three states: pending, fulfilled, and rejected.

  • Async/Await: async keyword is used to define an async function, which is a function that returns a promise. The await keyword is used to wait for a promise to be resolved before moving on to the next line of code.

Callback functions are one of the oldest and most basic ways to handle async operations in JavaScript. A callback function is a function that is passed as an argument to another function and executed when the async operation completes. For example, the following code uses the setTimeout function, which is a JavaScript function that runs a callback after a specified amount of time:

setTimeout(() => {
    console.log("Hello, World!");
}, 1000);
console.log("This will run first.");


// example 2.

let arr =[1,2,3,4,5,6];

function newarray(a,callbck) {
    let ans=[];
    for(i=0;i<a.length;i++){
        let element= callbck(a[i])
        ans.push(element)
    }
    console.log(ans)
}
newarray(arr,(a)=>{return a*10})  //we passed arrow function as callbck
newarray([3,4,3,2,1,4,6,4,2],(a)=>{return a/2})

In this example, the setTimeout function is used to call the callback function after 1 second. Meanwhile, the program continues to execute the next line of code, which logs "This will run first."

Promises are a more recent addition to JavaScript and provide a more elegant way to handle async operations. A promise is an object that represents the eventual completion (or failure) of an async operation and its resulting value. A promise has three states: pending, fulfilled, and rejected. For example, the following code uses the fetch function, which returns a promise that resolves with the response of the request, to retrieve data from an API:

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.log(error))

//example 2. 
let pr =  new Promise((resolve,reject)=>{
 resolve("congrats !! promise is resolved")    //you can pass only one either resolve or reject
   //reject("sorry! promise is rejected")
})
pr.then((para)=>{                 //In .then we pass 2 arrow function 1st for resolved and 2nd for reject 
    console.log(para)
},(para2)=>{
    console.log(para2)
})
                                 //insted of passing 2 arraow function in .then we can also use .then.catch
pr.then((para)=>{                  
   console.log(para)
}).catch((error)=>{
    console.log(error)
})

In this example, the fetch function returns a promise that resolves with the JSON data from the API. The then method is used to handle the resolved data, and the catch method is used to handle any errors that may occur.

Another way to handle async operations is through the use of async and await. The async keyword is used to define an async function, which is a function that returns a promise. The await keyword is used to wait for a promise to be resolved before moving on to the next line of code.

async function getData() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

//e.g 2.
let url = "https://catfact.ninja/fact" ;
let h2 = document.querySelector("h2")

async function fetchdata(){
    let response = await fetch(url);     //fetch returns promise so you need to wait for it if you dont wait then promise will be shown pending
    console.log(response);

    let data = await response.json();    //if you remove await you see pending promise
    console.log(data)

    h2.innerHTML=data.fact;
}
fetchdata();

In this example, the await keyword is used to wait for the promise returned by the fetch function to resolve, and the try and catch statement is used to handle errors.

Asynchronous programming can make your code more efficient and responsive by allowing multiple operations to run at the same time. However, it can also make your code more complex and harder to debug. It's important to choose the right tool for the job and have a good understanding of how async operations work in order to write effective and maintainable code.

In conclusion, Asynchronous programming is a complex topic in JavaScript, and it is important to understand the different ways of handling async operations and when to use them, such as callbacks, promises, async/await, generators, and web workers. You should also understand the event loop, which is the mechanism that handles async operations in javascript. It's important to choose the right tool for the job and have a good understanding of how async operations work in order to write effective and maintainable code.