Introduction to Asynchronous Programming
In JavaScript, asynchronous programming allows you to execute code without blocking the main thread. This is particularly useful for operations that might take some time to complete, such as:
- Fetching data from a server
- Reading files
- Executing complex calculations
Callbacks
Callbacks were the original way of handling asynchronous operations in JavaScript.
function fetchData(callback) {
setTimeout(() => {
callback('Data fetched!');
}, 2000);
}
fetchData((result) => {
console.log(result); // Outputs: Data fetched!
});
While callbacks work, they can lead to “callback hell” when dealing with multiple asynchronous operations.
Promises
Promises provide a more structured way to handle asynchronous operations.
Creating a Promise
let myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise resolved!');
}, 2000);
});
myPromise.then((result) => {
console.log(result); // Outputs: Promise resolved!
}).catch((error) => {
console.error(error);
});
Chaining Promises
Promises can be chained, making it easier to handle sequences of asynchronous operations:
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Async/Await
Async/await is syntactic sugar built on top of promises, making asynchronous code look and behave more like synchronous code.
Basic Usage
async function fetchData() {
try {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
fetchData();
Multiple Asynchronous Operations
async function fetchMultipleData() {
try {
let [response1, response2] = await Promise.all([
fetch('https://api.example.com/data1'),
fetch('https://api.example.com/data2')
]);
let data1 = await response1.json();
let data2 = await response2.json();
console.log(data1, data2);
} catch (error) {
console.error('Error:', error);
}
}
Error Handling
Proper error handling is crucial in asynchronous programming:
async function fetchDataWithErrorHandling() {
try {
let response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
let data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
Practical Example: Weather App
Let’s create a simple weather app that fetches weather data from an API:
<!DOCTYPE html>
<html>
<body>
<h2>Weather App</h2>
<input type="text" id="cityInput" placeholder="Enter city name">
<button id="getWeather">Get Weather</button>
<div id="weatherResult"></div>
<script>
const apiKey = 'YOUR_API_KEY'; // Replace with your actual API key
const getWeatherButton = document.getElementById('getWeather');
const cityInput = document.getElementById('cityInput');
const weatherResult = document.getElementById('weatherResult');
getWeatherButton.addEventListener('click', async () => {
const city = cityInput.value;
try {
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`);
if (!response.ok) {
throw new Error('City not found');
}
const data = await response.json();
weatherResult.textContent = `Temperature in ${city}: ${data.main.temp}°C`;
} catch (error) {
weatherResult.textContent = `Error: ${error.message}`;
}
});
</script>
</body>
</html>
Note: You’ll need to replace ‘YOUR_API_KEY’ with an actual API key from OpenWeatherMap.
Practice Exercise
- Extend the weather app to display more information (e.g., humidity, wind speed).
- Add error handling for network issues.
- Implement a loading indicator while the data is being fetched.
- Use
Promise.all()
to fetch weather data for multiple cities simultaneously.
Conclusion
This lesson covered the basics of asynchronous programming in JavaScript, including callbacks, promises, and async/await syntax. These concepts are crucial for modern web development, especially when working with APIs and handling time-consuming operations. In the next lesson, we’ll explore more advanced JavaScript topics such as modules and build tools.
Remember to practice these concepts by working on the weather app and creating your own projects that involve asynchronous operations!