📖 JavaScript Async/Await
Asynchronous programming in JavaScript allows you to execute code without blocking the main thread. This means JavaScript can handle tasks that might take time to complete, such as fetching data from a server or reading a file, without freezing the entire program until the task is finished. Instead, the program can continue executing other code while waiting for the asynchronous task to complete.
Single-Threaded Nature of JavaScript
JavaScript is single-threaded, meaning it can only execute one task at a time. However, with asynchronous programming, JavaScript can initiate long-running tasks and continue executing other code while waiting for those tasks to complete.
How Asynchronous Programming Works
- Callbacks
- A function passed as an argument to another function, executed after some operation has been completed.
- Promises
- An object representing the eventual completion or failure of an asynchronous operation.
- Async/Await
- A newer way to write asynchronous code that looks synchronous, built on promises.
Definition and Syntax of Async/Await
Async functions are a newer way to write asynchronous code in JavaScript. They are built on promises and allow you to write asynchronous code that looks synchronous.
Async Function Syntax
async function exampleFunction() {
let result = await someAsyncOperation();
console.log(result);
}
In this example:
- The
async
keyword is added before a function declaration to make it an async function. - Inside an async function, the
await
keyword is used to pause the execution of the function until the promise is resolved. - The function execution resumes once the promise is resolved, and the resolved value is assigned to the variable.
Simulating Asynchronous Operations
Before diving into real-world examples, let's simulate an asynchronous operation using a simple delay function.
// Simulating an asynchronous operation
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function runAsyncOperation() {
console.log('Operation started');
await delay(2000);
console.log('Operation completed');
}
runAsyncOperation();
In this example, the delay
function returns a promise that resolves after a specified number of milliseconds. The runAsyncOperation
function waits for the delay to complete before logging the final message.
Example: Fetching Weather Data
We can use async/await to handle asynchronous operations more elegantly than using promises alone. In this example, we fetch weather data from an API.
// Function to fetch weather data
async function fetchWeatherData(location) {
const url = `https://wttr.in/${location}?format=j1`;
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const weatherData = await response.json();
return weatherData;
} catch (error) {
console.error('Fetching weather data failed:', error);
throw error;
}
}
// Function to display weather data
function displayWeatherData(data) {
const currentCondition = data.current_condition[0];
console.log(`Temperature: ${currentCondition.temp_C}°C`);
console.log(`Weather: ${currentCondition.weatherDesc[0].value}`);
}
// Using the async function
async function getWeather(location) {
try {
const weatherData = await fetchWeatherData(location);
displayWeatherData(weatherData);
} catch (error) {
console.error('Error fetching and displaying weather data:', error);
}
}
// Call the function
getWeather('London');
In this example:
- The
fetchWeatherData
function fetches weather data from the API using async/await and returns the data. - The
displayWeatherData
function logs the weather data to the console. - The
getWeather
function callsfetchWeatherData
and handles any errors that might occur during the fetch operation.
Putting It Into Action
Create an HTML file with the following structure and include the provided script. This script will demonstrate how to fetch weather data using async/await and log the results to the console.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Async/Await Example</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
<div class="container mt-5">
<h1>Simple Weather App</h1>
</div>
<script>
async function fetchWeatherData(location) {
const url = `https://wttr.in/${location}?format=j1`;
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const weatherData = await response.json();
return weatherData;
} catch (error) {
console.error('Fetching weather data failed:', error);
throw error;
}
}
function displayWeatherData(data) {
const currentCondition = data.current_condition[0];
console.log(`Temperature: ${currentCondition.temp_C}°C`);
console.log(`Weather: ${currentCondition.weatherDesc[0].value}`);
}
async function getWeather(location) {
try {
const weatherData = await fetchWeatherData(location);
displayWeatherData(weatherData);
} catch (error) {
console.error('Error fetching and displaying weather data:', error);
}
}
getWeather('London');
</script>
</body>
>
In this example, we use async/await to fetch and display weather data when the user submits the form. The fetchWeatherData
function retrieves the data, and the displayWeatherData
function updates the DOM with the fetched data.
In order to check your learning, you should attempt to create a solution before revealing the provided solution below.
Challenge
Modify the example to include a feature where users can enter a location and click a button to fetch and display the weather data for that location.
Include the following HTML structure in your page to implement the form for fetching weather data:
<form id="weatherForm">
<div class="mb-3">
<label for="locationInput" class="form-label">Enter Location:</label>
<input type="text" id="locationInput" class="form-control" placeholder="Enter city name">
</div>
<button type="submit" class="btn btn-primary">Get Weather</button>
</form>
<div id="weatherData" class="mt-3"></div>
// JavaScript Code
document.getElementById('weatherForm').addEventListener('submit', async function(event) {
event.preventDefault();
const location = document.getElementById('locationInput').value;
try {
const weatherData = await fetchWeatherData(location);
displayWeatherData(weatherData);
} catch (error) {
document.getElementById('weatherData').innerHTML = '<p>Error fetching weather data. Please try again.</p>';
}
});