Assignments of Day 15: Asynchronous JavaScript

Rashmi Mishra
0

 

Assignments of Day 15: Asynchronous JavaScript

These assignments will help you understand and practice the key concepts of Callbacks, Promises, and Async/Await in JavaScript.


Assignment 1: Using Callbacks for Asynchronous Operations

Task:

Write a function getUserData(callback) that simulates an asynchronous operation of fetching user data. The function should use setTimeout to simulate a 2-second delay before invoking the callback function with some sample user data.

Then, write a handleUserData() function to process the user data returned by getUserData().

Steps:

1.  Create a function getUserData(callback) that simulates fetching user data.

2.  Call getUserData() and pass the handleUserData function as the callback.

3.  Display the processed data in handleUserData().

javascript

Copy code

// Step 1: Function to simulate fetching user data asynchronously using setTimeout

function getUserData(callback) {

  setTimeout(() => {

    const user = { name: "Alice", age: 25, country: "USA" };

    console.log("User data fetched!");

    callback(user); // Step 2: Passing the user data to the callback

  }, 2000); // Simulating a 2-second delay

}

 

// Step 2: Function to handle the fetched data

function handleUserData(user) {

  console.log(`Name: ${user.name}`);

  console.log(`Age: ${user.age}`);

  console.log(`Country: ${user.country}`);

}

 

// Step 3: Call the getUserData function with the handleUserData callback

getUserData(handleUserData);

Explanation:

  • The getUserData() function simulates a delay using setTimeout() and then calls the callback function (handleUserData()) with the user data after 2 seconds.
  • handleUserData() is the callback that processes and prints the user data.

Assignment 2: Converting Callbacks to Promises

Task:

Rewrite the getUserData() function from Assignment 1 to use a Promise instead of a callback.

Steps:

1.  Replace the callback mechanism with a Promise.

2.  Use .then() and .catch() to handle the result and errors.

javascript

Copy code

// Step 1: Modify getUserData to return a promise

function getUserData() {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const user = { name: "Bob", age: 30, country: "UK" };

      console.log("User data fetched!");

      resolve(user); // Resolving the promise with user data

    }, 2000); // Simulating a 2-second delay

  });

}

 

// Step 2: Using the promise with .then() and .catch()

getUserData()

  .then(user => {

    console.log(`Name: ${user.name}`);

    console.log(`Age: ${user.age}`);

    console.log(`Country: ${user.country}`);

  })

  .catch(error => {

    console.log("Error:", error);

  });

Explanation:

  • Instead of using callbacks, the getUserData() function returns a Promise.
  • The .then() method handles the resolved value (user data), and .catch() is used to handle any errors that might occur.

Assignment 3: Using Promise Chaining

Task:

Create a series of asynchronous tasks using promises. The tasks are as follows:

1.  Fetch user data (using a promise).

2.  Update the user's age.

3.  Save the updated user data.

Use promise chaining to execute these tasks in sequence.

Steps:

1.  Create a promise to fetch the user data.

2.  Chain .then() to update the age.

3.  Chain another .then() to save the updated data.

javascript

Copy code

// Step 1: Promise to fetch user data

function getUserData() {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const user = { name: "Charlie", age: 35, country: "Canada" };

      console.log("User data fetched!");

      resolve(user); // Resolving the promise with user data

    }, 2000);

  });

}

 

// Step 2: Promise to update the user's age

function updateUserAge(user, newAge) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      user.age = newAge;

      console.log("User age updated!");

      resolve(user); // Resolving with updated user data

    }, 1000);

  });

}

 

// Step 3: Promise to save the updated user data

function saveUserData(user) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      console.log("User data saved!");

      resolve(user); // Resolving with the saved user data

    }, 1000);

  });

}

 

// Step 4: Chain the promises to perform the tasks sequentially

getUserData()

  .then(user => updateUserAge(user, 40)) // Updating the user's age

  .then(updatedUser => saveUserData(updatedUser)) // Saving the updated data

  .then(finalUser => {

    console.log(`Final User: ${JSON.stringify(finalUser)}`);

  })

  .catch(error => {

    console.log("Error:", error);

  });

Explanation:

  • We chain promises using .then() to ensure that each task is completed before the next one begins.
  • The user data is fetched, updated, and then saved sequentially.

Assignment 4: Using Async/Await for Cleaner Code

Task:

Rewrite the promise chaining from Assignment 3 using async/await syntax for a cleaner, more synchronous-like flow.

Steps:

1.  Create an async function.

2.  Use await to pause the execution until the promise resolves.

3.  Handle errors using try...catch.

javascript

Copy code

// Step 1: Modify functions to return promises (same as previous assignment)

 

function getUserData() {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const user = { name: "David", age: 28, country: "Australia" };

      console.log("User data fetched!");

      resolve(user);

    }, 2000);

  });

}

 

function updateUserAge(user, newAge) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      user.age = newAge;

      console.log("User age updated!");

      resolve(user);

    }, 1000);

  });

}

 

function saveUserData(user) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      console.log("User data saved!");

      resolve(user);

    }, 1000);

  });

}

 

// Step 2: Create an async function to handle the operations

async function performUserTasks() {

  try {

    const user = await getUserData(); // Wait for user data

    const updatedUser = await updateUserAge(user, 45); // Wait for the updated user data

    const savedUser = await saveUserData(updatedUser); // Wait for saving the user data

    console.log(`Final User: ${JSON.stringify(savedUser)}`);

  } catch (error) {

    console.log("Error:", error);

  }

}

 

// Step 3: Call the async function

performUserTasks();

Explanation:

  • The performUserTasks function is declared as async, allowing us to use await for each promise.
  • await pauses the execution until each promise resolves, making the flow of code easier to follow, compared to the .then() method.

Assignment 5: Error Handling with Async/Await

Task:

Write an async function to fetch data from a simulated API, process it, and handle errors appropriately using try...catch.

Steps:

1.  Use async/await to fetch data.

2.  Use try...catch for error handling.

javascript

Copy code

// Simulating an API call using a promise

function fetchDataFromAPI() {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const success = true; // Change to false to simulate an error

      if (success) {

        resolve("Data fetched successfully!");

      } else {

        reject("Failed to fetch data.");

      }

    }, 2000);

  });

}

 

// Async function to fetch and process data

async function getProcessedData() {

  try {

    const data = await fetchDataFromAPI(); // Await the promise

    console.log(data);

    console.log("Processing data...");

    // Simulating data processing

  } catch (error) {

    console.log("Error:", error); // Catching any errors that occur

  }

}

 

// Calling the async function

getProcessedData();

Explanation:

  • The fetchDataFromAPI() function simulates a successful or failed API call.
  • The getProcessedData() function is async, and inside it, we use await to handle the promise and try...catch to handle errors.

Conclusion:

By completing these assignments, you will gain a strong understanding of asynchronous JavaScript and be comfortable with using callbacks, promises, and async/await for managing asynchronous operations in your code.

4o mini

You said:

give some more to understand well

ChatGPT said:

ChatGPT

Here are additional assignments to help you gain a deeper understanding of Asynchronous JavaScript concepts, focusing on Callbacks, Promises, and Async/Await. These exercises will provide more practical applications and scenarios for you to explore.


Assignment 6: Simulating a Database Fetch Operation (Callbacks)

Task:

Simulate a database fetch operation using a callback. The function should return a list of users after a 2-second delay. You need to process this list in the callback function.

Steps:

1.  Create a function fetchDatabase(callback) that simulates a fetch operation with setTimeout.

2.  Process the data inside the callback.

javascript

Copy code

// Simulating a database fetch operation

function fetchDatabase(callback) {

  setTimeout(() => {

    const users = [

      { name: "John", age: 28 },

      { name: "Jane", age: 34 },

      { name: "Alice", age: 22 }

    ];

    console.log("Database fetched!");

    callback(users); // Passing the fetched data to the callback

  }, 2000);

}

 

// Process the data in a callback

function processUserData(users) {

  users.forEach(user => {

    console.log(`Name: ${user.name}, Age: ${user.age}`);

  });

}

 

// Calling fetchDatabase with a callback

fetchDatabase(processUserData);

Explanation:

  • fetchDatabase() simulates a database fetch and uses a callback to pass the data.
  • The processUserData() function is the callback that processes the list of users.

Assignment 7: Promise Chaining with Multiple Steps

Task:

You have three asynchronous tasks:

1.  Fetch a user's details.

2.  Fetch their order history.

3.  Fetch the shipping status of their last order.

Use promises and chain these tasks in sequence.

Steps:

1.  Create promises to fetch user details, order history, and shipping status.

2.  Chain these promises using .then().

javascript

Copy code

// Fetch user details

function fetchUserDetails() {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const user = { name: "Bob", id: 1 };

      console.log("User details fetched!");

      resolve(user); // Resolving with user details

    }, 1000);

  });

}

 

// Fetch order history

function fetchOrderHistory(userId) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const orders = [

        { orderId: 101, status: "shipped" },

        { orderId: 102, status: "pending" }

      ];

      console.log("Order history fetched!");

      resolve(orders); // Resolving with order details

    }, 1000);

  });

}

 

// Fetch shipping status

function fetchShippingStatus(orderId) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const status = "shipped";

      console.log("Shipping status fetched!");

      resolve(status); // Resolving with shipping status

    }, 1000);

  });

}

 

// Chain the promises

fetchUserDetails()

  .then(user => fetchOrderHistory(user.id))

  .then(orders => fetchShippingStatus(orders[0].orderId))

  .then(status => console.log(`Last order shipping status: ${status}`))

  .catch(error => console.log("Error:", error));

Explanation:

  • Each task is wrapped in a promise.
  • The tasks are chained using .then() to execute them in sequence.
  • Errors are caught in the .catch() block.

Assignment 8: Using Async/Await with Multiple API Calls

Task:

Rewrite the sequence of asynchronous tasks from Assignment 7 using async/await. The goal is to fetch user details, order history, and shipping status, then log the final status.

Steps:

1.  Use async/await to fetch the user details, order history, and shipping status.

2.  Use try...catch for error handling.

javascript

Copy code

// Simulate fetching user details

function fetchUserDetails() {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const user = { name: "Sam", id: 2 };

      resolve(user);

    }, 1000);

  });

}

 

// Simulate fetching order history

function fetchOrderHistory(userId) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const orders = [

        { orderId: 103, status: "shipped" },

        { orderId: 104, status: "pending" }

      ];

      resolve(orders);

    }, 1000);

  });

}

 

// Simulate fetching shipping status

function fetchShippingStatus(orderId) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const status = "pending";

      resolve(status);

    }, 1000);

  });

}

 

// Async function using await to handle tasks sequentially

async function getShippingStatus() {

  try {

    const user = await fetchUserDetails(); // Await for user details

    const orders = await fetchOrderHistory(user.id); // Await for orders

    const status = await fetchShippingStatus(orders[0].orderId); // Await for shipping status

    console.log(`Last order shipping status: ${status}`);

  } catch (error) {

    console.log("Error:", error);

  }

}

 

// Call the async function

getShippingStatus();

Explanation:

  • async function getShippingStatus() handles asynchronous tasks with await.
  • The code is cleaner and easier to follow compared to promise chaining.

Assignment 9: Simulating an API Error Handling with Async/Await

Task:

Simulate an error while fetching the shipping status. Modify the fetchShippingStatus function to reject the promise if the order is "pending". Handle the error gracefully in the async function.

Steps:

1.  Modify fetchShippingStatus to reject a promise for pending orders.

2.  Use try...catch to handle errors in the async function.

javascript

Copy code

// Simulate fetching user details

function fetchUserDetails() {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const user = { name: "Mike", id: 3 };

      resolve(user);

    }, 1000);

  });

}

 

// Simulate fetching order history

function fetchOrderHistory(userId) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const orders = [

        { orderId: 105, status: "shipped" },

        { orderId: 106, status: "pending" }

      ];

      resolve(orders);

    }, 1000);

  });

}

 

// Simulate fetching shipping status with potential rejection

function fetchShippingStatus(orderId) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const status = "pending"; // Simulate an issue with pending status

      if (status === "pending") {

        reject("Shipping status is pending. Cannot proceed.");

      } else {

        resolve(status);

      }

    }, 1000);

  });

}

 

// Async function to handle the sequence with error handling

async function getShippingStatus() {

  try {

    const user = await fetchUserDetails(); // Await for user details

    const orders = await fetchOrderHistory(user.id); // Await for orders

    const status = await fetchShippingStatus(orders[1].orderId); // This will throw error as status is pending

    console.log(`Last order shipping status: ${status}`);

  } catch (error) {

    console.log("Error:", error); // Handle error

  }

}

 

// Call the async function

getShippingStatus();

Explanation:

  • fetchShippingStatus() has been modified to simulate an error when the shipping status is "pending".
  • The error is caught in the catch block and logged.

Assignment 10: Simulating a Timeout in Async/Await

Task:

Simulate a timeout in the asynchronous operation by rejecting the promise if the operation takes too long. Use async/await to manage this.

Steps:

1.  Modify the fetchUserDetails function to reject after a timeout.

2.  Handle the timeout error gracefully with try...catch.

javascript

Copy code

// Simulating a delayed fetch operation with timeout

function fetchUserDetails() {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const user = { name: "Tom", id: 4 };

      reject("Timeout: Data fetch took too long.");

    }, 5000); // Reject after 5 seconds to simulate a timeout

  });

}

 

// Async function to handle the fetch with timeout

async function getUserDataWithTimeout() {

  try {

    const user = await fetchUserDetails();

    console.log(`User: ${user.name}`);

  } catch (error) {

    console.log("Error:", error); // Catch timeout error

  }

}

 

// Call the async function

getUserDataWithTimeout();

Explanation:

  • The fetchUserDetails() function simulates a delay and rejects the promise after 5 seconds, simulating a timeout.
  • The error is caught in the catch block and handled accordingly.

Conclusion:

These additional assignments provide more complex scenarios and practical use cases of Callbacks, Promises, and Async/Await. By practicing these, you'll develop a deeper understanding of how to handle asynchronous operations, error handling, and the benefits of each approach in real-world JavaScript applications.

4o mini

You said:

give some more to understand this concept well as i am the beginner

ChatGPT said:

ChatGPT

Here are additional assignments with a focus on Asynchronous JavaScript, designed to help you deepen your understanding as a beginner. These exercises will provide more hands-on practice with callbacks, promises, and async/await.


Assignment 11: Simple Callback Function

Task:

Create a simple callback function that simulates a user login process. The function should return the login status after a 1-second delay.

Steps:

1.  Create a function userLogin that simulates a login process.

2.  Use a callback to display the login success or failure message.

javascript

Copy code

// Simulate a user login process

function userLogin(username, password, callback) {

  setTimeout(() => {

    if (username === "user" && password === "pass") {

      callback(null, "Login successful!"); // Success

    } else {

      callback("Login failed. Please check your credentials.", null); // Failure

    }

  }, 1000);

}

 

// Process the login result in a callback

function handleLoginResult(error, message) {

  if (error) {

    console.log(error);

  } else {

    console.log(message);

  }

}

 

// Call the login function with a callback

userLogin("user", "pass", handleLoginResult);

Explanation:

  • The userLogin() function simulates a login operation with a 1-second delay.
  • A callback function handleLoginResult() processes the login result.

Assignment 12: Promises with Success and Failure

Task:

Create a promise that resolves if the user is logged in, and rejects if the login fails. Handle both cases using .then() and .catch().

Steps:

1.  Create a promise for the login process.

2.  Handle success and failure using .then() and .catch().

javascript

Copy code

// Simulate a login process returning a promise

function login(username, password) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      if (username === "admin" && password === "admin123") {

        resolve("Login successful!"); // Resolve on success

      } else {

        reject("Login failed. Incorrect credentials."); // Reject on failure

      }

    }, 1000);

  });

}

 

// Use the promise to handle success and failure

login("admin", "admin123")

  .then((message) => console.log(message))

  .catch((error) => console.log(error));

Explanation:

  • The login() function returns a promise that resolves or rejects based on the login credentials.
  • The .then() block processes the success, and the .catch() block handles the error.

Assignment 13: Promise Chaining

Task:

Use promise chaining to simulate fetching user data, followed by fetching their orders, and finally fetching their order status.

Steps:

1.  Create promises for user data, orders, and order status.

2.  Chain the promises using .then().

javascript

Copy code

// Fetch user details

function getUserDetails() {

  return new Promise((resolve) => {

    setTimeout(() => {

      const user = { id: 1, name: "Alice" };

      resolve(user);

    }, 1000);

  });

}

 

// Fetch user orders

function getUserOrders(userId) {

  return new Promise((resolve) => {

    setTimeout(() => {

      const orders = [{ orderId: 101, status: "shipped" }];

      resolve(orders);

    }, 1000);

  });

}

 

// Fetch order status

function getOrderStatus(orderId) {

  return new Promise((resolve) => {

    setTimeout(() => {

      const status = "shipped";

      resolve(status);

    }, 1000);

  });

}

 

// Chain promises

getUserDetails()

  .then((user) => {

    console.log(`User: ${user.name}`);

    return getUserOrders(user.id); // Fetch orders

  })

  .then((orders) => {

    console.log("Orders:", orders);

    return getOrderStatus(orders[0].orderId); // Fetch order status

  })

  .then((status) => {

    console.log(`Order status: ${status}`);

  })

  .catch((error) => console.log("Error:", error));

Explanation:

  • The promises are chained one after the other. Each .then() processes the result from the previous promise and passes the value to the next function.

Assignment 14: Using Async/Await for Sequential Tasks

Task:

Use async/await to fetch user details, their orders, and the order status in a sequential manner.

Steps:

1.  Use async/await to handle the tasks in a sequence.

2.  Handle any errors that may occur.

javascript

Copy code

// Fetch user details

function getUserDetails() {

  return new Promise((resolve) => {

    setTimeout(() => {

      const user = { id: 1, name: "Bob" };

      resolve(user);

    }, 1000);

  });

}

 

// Fetch user orders

function getUserOrders(userId) {

  return new Promise((resolve) => {

    setTimeout(() => {

      const orders = [{ orderId: 102, status: "pending" }];

      resolve(orders);

    }, 1000);

  });

}

 

// Fetch order status

function getOrderStatus(orderId) {

  return new Promise((resolve) => {

    setTimeout(() => {

      const status = "pending";

      resolve(status);

    }, 1000);

  });

}

 

// Async function using await

async function getOrderInfo() {

  try {

    const user = await getUserDetails();

    console.log(`User: ${user.name}`);

   

    const orders = await getUserOrders(user.id);

    console.log("Orders:", orders);

   

    const status = await getOrderStatus(orders[0].orderId);

    console.log(`Order status: ${status}`);

  } catch (error) {

    console.log("Error:", error);

  }

}

 

// Call the async function

getOrderInfo();

Explanation:

  • The async function getOrderInfo() handles each asynchronous task sequentially with await.
  • Errors are caught with try...catch to handle exceptions.

Assignment 15: Handling Multiple Asynchronous Tasks with Async/Await

Task:

Fetch the user details and order history simultaneously (in parallel) using async/await. Use Promise.all() to handle multiple promises at once.

Steps:

1.  Use Promise.all() to fetch user details and orders in parallel.

2.  Await both tasks and display the results.

javascript

Copy code

// Simulate fetching user details

function getUserDetails() {

  return new Promise((resolve) => {

    setTimeout(() => {

      const user = { id: 2, name: "Charlie" };

      resolve(user);

    }, 1000);

  });

}

 

// Simulate fetching order history

function getOrderHistory() {

  return new Promise((resolve) => {

    setTimeout(() => {

      const orders = [

        { orderId: 201, status: "delivered" },

        { orderId: 202, status: "shipped" }

      ];

      resolve(orders);

    }, 1000);

  });

}

 

// Async function to fetch both user details and order history

async function fetchUserAndOrders() {

  try {

    const [user, orders] = await Promise.all([getUserDetails(), getOrderHistory()]);

    console.log(`User: ${user.name}`);

    console.log("Orders:", orders);

  } catch (error) {

    console.log("Error:", error);

  }

}

 

// Call the async function

fetchUserAndOrders();

Explanation:

  • Promise.all() is used to fetch both user details and order history simultaneously.
  • The results are awaited, and once both promises resolve, their results are processed.

Assignment 16: Simulating Delayed API Response

Task:

Simulate an API call with a delayed response. Use async/await to manage the delayed response and handle the result.

Steps:

1.  Simulate a delayed response using setTimeout.

2.  Use async/await to handle the delay.

javascript

Copy code

// Simulate a delayed API call

function apiCall() {

  return new Promise((resolve) => {

    setTimeout(() => {

      resolve("API call completed!");

    }, 3000); // 3-second delay

  });

}

 

// Async function to handle delayed response

async function fetchApiData() {

  console.log("Fetching data...");

  const response = await apiCall(); // Await the API call

  console.log(response); // Log the response after 3 seconds

}

 

// Call the async function

fetchApiData();

Explanation:

  • The apiCall() function simulates an API call with a 3-second delay using setTimeout.
  • async/await is used to wait for the result before proceeding.

Conclusion:

These assignments build upon the concepts of callbacks, promises, and async/await, helping you get hands-on practice with asynchronous JavaScript. By solving these problems, you will better understand how JavaScript handles asynchronous operations, how to manage multiple tasks, and how to handle errors effectively. Keep practicing these concepts to improve your understanding and skills!

4o mini

You said:

Post a Comment

0Comments

Post a Comment (0)